#![allow(unused)]
use std::path::PathBuf;
use std::fs::{File,metadata,OpenOptions,rename,remove_file};
use std::io::{BufRead, BufReader, Write,Read};
use std::process::Command;
pub fn compile(path:&str){
if let Err(_)=metadata(path){
panic!("{}文件不存在",path)
}
if !is_elf64(path){
panic!("{}不是elf64文件",path)
}
let file_sectors = match get_file_sectors(path){
Ok(size)=>{size}
Err(_)=>{
panic!("无法获取到文件相关信息");
}
};
modify_kernel_sectors("ospre/common/boot_loader_equ.asm",file_sectors);
nasm_compliy("ospre/bin/boot.bin","ospre/boot/boot.asm");
nasm_compliy("ospre/bin/loader.bin","ospre/loader/loader.asm");
nasm_compliy("ospre/bin/loader2.bin","ospre/loader/loader2.asm");
}
fn get_file_sectors(file_path: &str) -> Result<u64, std::io::Error>{
let meta=metadata(file_path)?;
Ok((meta.len()+512)/512)
}
fn modify_kernel_sectors(file_path: &str,sectors:u64){
let file = File::open(file_path).expect("文件打开失败");
let mut dir_path = PathBuf::from(file_path);
dir_path.pop();
let dp=dir_path.display();
let director=&(dp.to_string());
let reader = BufReader::new(file);
let mut new_file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true) .open(format!("{}/tmp",director))
.expect("创建新文件失败");
for line in reader.lines() {
let mut line_str = line.expect("bootloader汇编宏文件读取失败");
if line_str.starts_with("KERNEL_ALL_SECTORS"){
line_str=format!("KERNEL_ALL_SECTORS equ {}",sectors);
}
writeln!(new_file, "{}", line_str).expect("文件写入失败");
}
remove_file(file_path);
rename(format!("{}/tmp",director),file_path);
}
fn nasm_compliy(input:&str,output:&str){
let output = Command::new("nasm")
.arg("-g")
.arg("-O0")
.arg("-o")
.arg(input)
.arg(output)
.output()
.unwrap();
let err_msg=String::from_utf8(output.stderr).unwrap();
if err_msg != "".to_string() {
println!("{}",err_msg);
}
}
pub fn is_elf64(file_path: &str)->bool{
let mut file = File::open(file_path).unwrap();
let mut buffer: [u8; 64] = [0_u8; 64];
let _=file.read_exact(&mut buffer);
if buffer[0]!=0x7f || buffer[1]!=69 || buffer[2]!=76 || buffer[3]!=70 {
return false;
}
return true;
}