ospre/compile/
mod.rs

1#![allow(unused)]
2
3use std::path::PathBuf;
4use std::fs::{File,metadata,OpenOptions,rename,remove_file};
5use std::io::{BufRead, BufReader, Write,Read};
6use std::process::Command;
7
8
9
10//用nasm编译boot、loader、loader2
11pub fn compile(path:&str){
12    // 判断文件是否存在
13 if let Err(_)=metadata(path){
14     panic!("{}文件不存在",path)
15 }
16
17 //判断文件是否为ELF64
18 if !is_elf64(path){
19     panic!("{}不是elf64文件",path)
20 }
21
22 //获取文件所占扇区数
23 let file_sectors = match get_file_sectors(path){
24     Ok(size)=>{size}
25     Err(_)=>{
26     panic!("无法获取到文件相关信息");
27     }
28 };
29
30 
31 //替换equ文件中扇区数
32 modify_kernel_sectors("ospre/common/boot_loader_equ.asm",file_sectors);
33
34 //调用nasm编译boot
35 nasm_compliy("ospre/bin/boot.bin","ospre/boot/boot.asm");
36 //调用nasm编译loader
37 nasm_compliy("ospre/bin/loader.bin","ospre/loader/loader.asm");
38 //调用nasm编译loader2
39 nasm_compliy("ospre/bin/loader2.bin","ospre/loader/loader2.asm");
40}
41
42
43//获取文件所占扇区数
44fn get_file_sectors(file_path: &str) -> Result<u64, std::io::Error>{
45 // let mut file=File::open(path)?;
46 let meta=metadata(file_path)?;
47 Ok((meta.len()+512)/512)
48}
49
50
51//修改boot_loader_equ.asm中的内核扇区数
52fn modify_kernel_sectors(file_path: &str,sectors:u64){
53 // 打开文件
54 let file = File::open(file_path).expect("文件打开失败");
55
56 //记录文件所在目录
57 let mut dir_path = PathBuf::from(file_path);
58 dir_path.pop();
59 let dp=dir_path.display();
60 let director=&(dp.to_string());
61
62 // 读取文件内容
63 let reader = BufReader::new(file);
64
65 // 创建一个新的文件,并打开写入模式
66 let mut new_file = OpenOptions::new()
67     .write(true)
68     .create(true)
69     .truncate(true) // 清空文件内容
70     .open(format!("{}/tmp",director))
71     .expect("创建新文件失败");
72    
73     
74     for line in reader.lines() {
75       let mut line_str = line.expect("bootloader汇编宏文件读取失败");
76       if line_str.starts_with("KERNEL_ALL_SECTORS"){
77          line_str=format!("KERNEL_ALL_SECTORS  equ {}",sectors);
78       }
79       writeln!(new_file, "{}", line_str).expect("文件写入失败");
80   }
81
82   // 删除旧文件
83   remove_file(file_path);
84   //重命名新文件
85   rename(format!("{}/tmp",director),file_path);
86}
87
88//编译boot文件
89fn nasm_compliy(input:&str,output:&str){
90 let output = Command::new("nasm")
91 .arg("-g")
92 .arg("-O0")
93 .arg("-o")
94 .arg(input)
95 .arg(output)
96 .output()
97 .unwrap();
98
99 let err_msg=String::from_utf8(output.stderr).unwrap();
100
101 if err_msg != "".to_string() {
102    println!("{}",err_msg);
103 }
104}
105
106//判断一个文件是否为ELF64
107pub fn is_elf64(file_path: &str)->bool{
108    let mut file = File::open(file_path).unwrap();
109    let mut buffer: [u8; 64] = [0_u8; 64];
110
111    // 读取 前64个字节,判断elf魔术和elf64的标志是否正确
112    let _=file.read_exact(&mut buffer);
113    if buffer[0]!=0x7f || buffer[1]!=69 || buffer[2]!=76 || buffer[3]!=70 {
114        return false;
115    }
116    return true;
117}