1. 内核加载器- 写内核加载器 loader- 将loader 写入硬盘- 在主引导扇区读入- 检测正确性- 跳转到 loader 执行[org 0x1000] dw 0x55aa; 用于判断错误MBR 的主要功能是读取内核加载器 并引导内核完成自举主引导扇区的结构 512B- 代码 446 B- 硬盘分区表 64B 4 * 16B- 魔数 0xaa55 0x55 0xaa读取内核加载器 就需要读取硬盘2. 读取硬盘- 扇区 硬盘读写的最小单位 512B- 机械臂 寻道时间是硬盘性能的主要瓶颈- 一般情况下一个磁道有 63 个扇区 主要是由于 BIOS 最大支持这么多- 磁道从外侧计数 所以C盘读写速度最快2.1 IDE / ATA PIO ModePIO port input output 端口输入输出模式端口 外部设备 内部寄存器IDE: integrated drive electronic 集成电子驱动器2.2 硬盘读写CHS 模式 柱面/ 磁头/ 磁道LBA 模式 *LBA28 1**28 128G的磁盘空间硬盘控制器端口0x1f0 : 16bit端口 用于读写数据0x1f1: 检测前一个指令的错误0x1f2 读写扇区的数量 最多256个0x1f3 起始扇区0-7为0x1f4 起始扇区的8-15位0x1f5 16-23位0x1f6 0-3位是起始扇区的24-27位 40表示主盘 1表示从盘 6 0chs模式 1表示lba模式5 7 位固定为10x1f7 out操作 0xec 表示识别硬盘0x20 表示读硬盘0x30 表示写硬盘in操作 / 8bit的数据第 0 位表示错误 ERR第 3 表示数据准备完毕 DRQ第 7 位表示硬盘是否繁忙 BSYPS: 我是使用vscode 中的 ssh 连接虚拟机中的文件 经常遇到需要重新连接的问题 很烦 所以 使用下面的连接的内容进行配置VS Code Remote-SSH: 彻底告别重复输入密码 - 排坑笔记 | 阿尔的代码屋 | 阿尔的代码屋 | 全栈技术笔记3. 写内核加载器; loader.asm [org 0x1000] dw 0x55aa ; 魔数 用来判断错误 ; 打印字符串 mov si, loading call print ; 阻塞 jmp $ print: mov ah, 0x0e .next: mov al, [si] cmp al, 0 jz .done int 0x10 inc si jmp .next .done: ret loading: db Booting onix..., 10, 13, 0;; boot.asm 修改 ; 1. 删去write_disk, 用不到 ; add error error: mov si, .msg call print hlt ; 让CPU停止 jmp $ .msg db Booting error , 10, 13, 0; 修改makefile中的编译master.img master.img: boot.bin loader.bin yes | bximage -q -hd16 -funccreate -sectsize512 -imgmodeflat master.img dd ifboot.bin ofmaster.img bs512 count1 convnotrunc dd ifloader.bin of master.img bs512 count4 seek2 convnotrunc这里代表将 boot.bin 写入第一个master.img的磁盘空间写入一个磁盘 512B将 loader.bin 写入第三个master.img 的磁盘空间 写入四个磁盘空间 512B * 4; 修改makefile中的编译规则 修改为模式规则 %.bin: %.asm nasm -f bin $ -o $在loader 读入内存 在 boot.bin 中将 loader 读取到内存; 修改 loader.asm ; 修改读的片段 mov edi, 0x1000 mov ecx, 2 ; 起始扇区 mov bl, 4 ; 读取的扇区数量 call read_disk ; 将loader加载到0x1000的位置 cmp word [0x1000], 0x55aa jnz error jmp 0: 0x1002 ; 进行执行loader将loader 放在 0x1000 的原因将 loader 放在 0x500 - 0x7bff将 内核 放在 0x7e00 - 0x9fbff 的区域在上电之后 硬件自动跳转到 0xffff0 的BIOS 入口地址 然后检查硬件 完成0x000-0x3fff位置的中断向量表的填写 然后 将MBR加载到0x7c00主引导扇区 boot.bin进行执行
OS开发(三)
1. 内核加载器- 写内核加载器 loader- 将loader 写入硬盘- 在主引导扇区读入- 检测正确性- 跳转到 loader 执行[org 0x1000] dw 0x55aa; 用于判断错误MBR 的主要功能是读取内核加载器 并引导内核完成自举主引导扇区的结构 512B- 代码 446 B- 硬盘分区表 64B 4 * 16B- 魔数 0xaa55 0x55 0xaa读取内核加载器 就需要读取硬盘2. 读取硬盘- 扇区 硬盘读写的最小单位 512B- 机械臂 寻道时间是硬盘性能的主要瓶颈- 一般情况下一个磁道有 63 个扇区 主要是由于 BIOS 最大支持这么多- 磁道从外侧计数 所以C盘读写速度最快2.1 IDE / ATA PIO ModePIO port input output 端口输入输出模式端口 外部设备 内部寄存器IDE: integrated drive electronic 集成电子驱动器2.2 硬盘读写CHS 模式 柱面/ 磁头/ 磁道LBA 模式 *LBA28 1**28 128G的磁盘空间硬盘控制器端口0x1f0 : 16bit端口 用于读写数据0x1f1: 检测前一个指令的错误0x1f2 读写扇区的数量 最多256个0x1f3 起始扇区0-7为0x1f4 起始扇区的8-15位0x1f5 16-23位0x1f6 0-3位是起始扇区的24-27位 40表示主盘 1表示从盘 6 0chs模式 1表示lba模式5 7 位固定为10x1f7 out操作 0xec 表示识别硬盘0x20 表示读硬盘0x30 表示写硬盘in操作 / 8bit的数据第 0 位表示错误 ERR第 3 表示数据准备完毕 DRQ第 7 位表示硬盘是否繁忙 BSYPS: 我是使用vscode 中的 ssh 连接虚拟机中的文件 经常遇到需要重新连接的问题 很烦 所以 使用下面的连接的内容进行配置VS Code Remote-SSH: 彻底告别重复输入密码 - 排坑笔记 | 阿尔的代码屋 | 阿尔的代码屋 | 全栈技术笔记3. 写内核加载器; loader.asm [org 0x1000] dw 0x55aa ; 魔数 用来判断错误 ; 打印字符串 mov si, loading call print ; 阻塞 jmp $ print: mov ah, 0x0e .next: mov al, [si] cmp al, 0 jz .done int 0x10 inc si jmp .next .done: ret loading: db Booting onix..., 10, 13, 0;; boot.asm 修改 ; 1. 删去write_disk, 用不到 ; add error error: mov si, .msg call print hlt ; 让CPU停止 jmp $ .msg db Booting error , 10, 13, 0; 修改makefile中的编译master.img master.img: boot.bin loader.bin yes | bximage -q -hd16 -funccreate -sectsize512 -imgmodeflat master.img dd ifboot.bin ofmaster.img bs512 count1 convnotrunc dd ifloader.bin of master.img bs512 count4 seek2 convnotrunc这里代表将 boot.bin 写入第一个master.img的磁盘空间写入一个磁盘 512B将 loader.bin 写入第三个master.img 的磁盘空间 写入四个磁盘空间 512B * 4; 修改makefile中的编译规则 修改为模式规则 %.bin: %.asm nasm -f bin $ -o $在loader 读入内存 在 boot.bin 中将 loader 读取到内存; 修改 loader.asm ; 修改读的片段 mov edi, 0x1000 mov ecx, 2 ; 起始扇区 mov bl, 4 ; 读取的扇区数量 call read_disk ; 将loader加载到0x1000的位置 cmp word [0x1000], 0x55aa jnz error jmp 0: 0x1002 ; 进行执行loader将loader 放在 0x1000 的原因将 loader 放在 0x500 - 0x7bff将 内核 放在 0x7e00 - 0x9fbff 的区域在上电之后 硬件自动跳转到 0xffff0 的BIOS 入口地址 然后检查硬件 完成0x000-0x3fff位置的中断向量表的填写 然后 将MBR加载到0x7c00主引导扇区 boot.bin进行执行