ospre 0.1.6

这是一个用于开发64位操作系统的前置工具,用于做boot、loader等工作。它需要你安装nasm编译器才能使用,使用方式请看文档
Documentation
#![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;



//用nasm编译boot、loader、loader2
pub fn compile(path:&str){
    // 判断文件是否存在
 if let Err(_)=metadata(path){
     panic!("{}文件不存在",path)
 }

 //判断文件是否为ELF64
 if !is_elf64(path){
     panic!("{}不是elf64文件",path)
 }

 //获取文件所占扇区数
 let file_sectors = match get_file_sectors(path){
     Ok(size)=>{size}
     Err(_)=>{
     panic!("无法获取到文件相关信息");
     }
 };

 
 //替换equ文件中扇区数
 modify_kernel_sectors("ospre/common/boot_loader_equ.asm",file_sectors);

 //调用nasm编译boot
 nasm_compliy("ospre/bin/boot.bin","ospre/boot/boot.asm");
 //调用nasm编译loader
 nasm_compliy("ospre/bin/loader.bin","ospre/loader/loader.asm");
 //调用nasm编译loader2
 nasm_compliy("ospre/bin/loader2.bin","ospre/loader/loader2.asm");
}


//获取文件所占扇区数
fn get_file_sectors(file_path: &str) -> Result<u64, std::io::Error>{
 // let mut file=File::open(path)?;
 let meta=metadata(file_path)?;
 Ok((meta.len()+512)/512)
}


//修改boot_loader_equ.asm中的内核扇区数
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);
}

//编译boot文件
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);
 }
}

//判断一个文件是否为ELF64
pub fn is_elf64(file_path: &str)->bool{
    let mut file = File::open(file_path).unwrap();
    let mut buffer: [u8; 64] = [0_u8; 64];

    // 读取 前64个字节,判断elf魔术和elf64的标志是否正确
    let _=file.read_exact(&mut buffer);
    if buffer[0]!=0x7f || buffer[1]!=69 || buffer[2]!=76 || buffer[3]!=70 {
        return false;
    }
    return true;
}