ospre 0.1.6

这是一个用于开发64位操作系统的前置工具,用于做boot、loader等工作。它需要你安装nasm编译器才能使用,使用方式请看文档
Documentation
#![allow(unused)]

use std::io::{SeekFrom,BufReader, BufWriter, Read, Write,Seek};
use std::collections::HashMap;
use std::fs::{File,metadata,OpenOptions};

//制作镜像文件
pub fn make(files_block: &HashMap<&str, u64>) -> std::io::Result<()> {
    let mut files_size=0_u64;
    match all_file_exist(files_block){
        Ok(size)=>{
            files_size=size;
        },
        Err(v)=>{
            for msg in v{
                println!("{}文件不存在",msg);
            }
            panic!("上述文件不存在,无法编译");
        }
    }
  
    println!("boot、loader、kernel文件总大小{}",files_size);

    //文件都存在,制作镜像
    let target_file_path="disk.img";
    let target_file = File::create(target_file_path)?;
    target_file.set_len(files_size/512+1)?;
    //写入boot、loader、loader2等文件
    for (file,block) in files_block{
         println!("文件:{},写入起始扇区号:{},大小:{}字节",file,block,metadata(file).unwrap().len());
         write_offset(file,target_file_path,block*512);
    }

    let disk_meta=metadata(target_file_path)?;
    println!("镜像文件总大小:{}字节",disk_meta.len());
    Ok(())
}



//循环判断需要写入磁盘镜像的文件是否都存在,不存在返回消息,存在则返回所有文件总大小
fn all_file_exist<'a>(file_block: &'a HashMap<&'a str, u64>)->Result<u64, Vec<&'a str>>{
    let mut size=0_u64;
    let mut v:Vec<&str>=Vec::new();
     // 迭代访问 HashMap 中的所有键值对
     for (file_path,_) in file_block {
        match metadata(file_path){
            Ok(meta)=>{
                size+=meta.len();
            },
            Err(_)=>{
                v.push(file_path);
            }
        }
    }

    if v.len()==0{
        Ok(size)
    }else{
        Err(v)
    }
}


//将一个文件写入另一个文件偏移量位offset字节处
fn write_offset(source_path:&str,target_path:&str,offset:u64)->std::io::Result<()>{
    let mut source_file = BufReader::new(File::open(source_path)?);
    let mut target_file = OpenOptions::new()
    .write(true)
    .create(true)
    .open(target_path)?;
    
    target_file.seek(SeekFrom::Start(offset))?;

    let mut buffer = [0; 1024]; //缓冲区
    loop {
        let bytes_read = source_file.read(&mut buffer)?;
        if bytes_read == 0 {
            break;
        }
        target_file.write(&buffer[0..bytes_read])?;
    }
    target_file.flush()?;
    drop(target_file);
    Ok(())
}