创建启动盘

102 阅读2分钟

开发简易操作系统就是制作一张含有操作系统并且能自动启动的磁盘

使用汇编写自启动程序

; 汇编代码
org 0x7c00    ; 程序加载到内存地址0x7c00

jmp entry     ; 从entry开始执行

entry:                   ; 设置运行时环境
	mov ax, 0
	mov ds, ax       ; 数据段
	mov es, ax       ; 附加数据段
	mov ss, ax       ; 栈段
	mov si, msg      ; 栈指针

print:
	mov al, [si]     ; si
	add si, 1        ; si自增
	cmp al, 0        ; 校验字符串是否到结尾
	je fin           ; 字符串结束跳到fin开始执行
	mov ah, 0x0e     
	mov bx, 15
	int 0x10         ; 调用硬件API将字符打印到屏幕上
	jmp print        ; 跳到print循环

fin:
	HLT              ; 让CPU进入睡眠状态
	jmp fin

msg:
	db 0x0a
	db "hello world"
	db 0
// 上面汇编代码的等价c语言代码

//msg:
//	db 0x0a 换行符
//	db "hello world"
//	db 0 字符串以0结束
char msg[] = {'\n','h','e','l','l','o',' ','w','o','r','l','d','\0'};

//print:
//	mov al, [si]     ; si
//	add si, 1        ; si自增
//	cmp al, 0        ; 校验字符串是否到结尾
//	je fin           ; 字符串结束跳到fin开始执行
//	mov ah, 0x0e     ; 调用硬件API的准备工作
//	mov bx, 15       ; 调用硬件API的准备工作
//	int 0x10         ; 调用硬件API将字符打印到屏幕上 相当于printf
//	jmp print        ; 跳到print循环
char *si = &msg[0];
char ch;
do {
    ch = *si;
    si ++;
    if(ch == '\0')
        goto fin
    printf("%c", ch);
} while (true);

将汇编代码生成机器指令

使用nasm编译器生成bin文件

nasm -f bin helloworld.asm -o helloworld.bin

使用任意16进制文件编辑器打开bin文件

机器指令.png

// 将机器指令写入img文件
public class MakeIMG {
    // 上面16进制的机器指令
    private static int[] binaryArray = new int[]{
            0xeb,0x00,0xb8,0x00,0x00,0x8e,0xd8,0x8e,0xc0,0x8e,0xd0,0xbe,0x23,0x7c,0x8a,0x04,
            0x83,0xc6,0x01,0x3c,0x00,0x74,0x09,0xb4,0x0e,0xbb,0x0f,0x00,0xcd,0x10,0xeb,0xee,
            0xf4,0xeb,0xfd,0x0a,0x68,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64,0x00
    };
    // 将机器指令写入myos.img文件
    private static void makeImgFile(String imgFilename) throws IOException {
        int length = binaryArray.length;
        DataOutputStream output = new DataOutputStream(new FileOutputStream(imgFilename));
        for(int i = 0;i < length;i ++) {
            output.writeByte(binaryArray[i]);
        }
        // 填充第一扇区到512字节
        for(int i = 0;i < 510-length;i ++) {
            output.writeByte(0x00);
        }
        // 最后两个字节必须是0x55 0xaa
        output.writeByte(0x55);
        output.writeByte(0xaa);
    }

    public static void main(String[] args) {
        try {
            MakeIMG.makeImgFile("myos.img");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在visual box创建虚拟机并将存储设置为创建的启动盘

设置软盘

设置软盘.png 启动后打印hello world

启动虚拟机.PNG