一、回顾及存在问题
前面我们讲了, bootloader的作用有三个:一是收集系统状态信息;二是将设置系统状态,以满足操作系统运行要求;三是加载和执行操作系统(kernel)。
我们已经完成了:
1. 驻留内存的引导程序;
2. 驻留在第1个引导扇区的bootloader编写,将内核程序加载到内存执行;
目前我们仅仅完成了第三项,我们还没有收集系统信息,也没有将系统转到保护模式,仍处于实模式状态。
因为bootloader越来越复杂,所以拟选择C语言来编写bootloader,程序在切换到保护模式之前,运行的程序是实模式,需要将其编译为实模式下的16位代码。
二、超过512字节bootloader限制----分2个阶段加载操作内容
1. 将前面部分代码进行复制为part4,并在src/bootloader目录下创建两个子目录stage1,stage2,将前面的boot.asm 移动到statge1中,并将其中的kernel.bin 修改为stage2.
注:磁盘中的数据加载到内存的位置是按照DOS实模式下内存分配布局进行的
2. 在stage1中为boot.asm编写makefile
boot.asm:这段代码的目的是作为一个启动扇区,从软盘读取内核文件并加载到内存中执行。它使用了BIOS中断和一些简单的数学运算来实现磁盘操作
修改boot.asmru如下:
lazybird@lazybird-home MSYS /d/GMY/buidos/part4
$ diff ../part3/src/bootloader/boot.asm src/bootloader/stage1/boot.asm
114c114
< mov si, file_kernel_bin
---
> mov si, file_stage2_bin
133c133
< mov [kernel_cluster], ax
---
> mov [stage2_cluster], ax
150c150
< mov ax, [kernel_cluster]
---
> mov ax, [stage2_cluster]
153c153
< add ax, 31 ; first cluster = (kernel_cluster - 2) * sectors_per_cluster + start_sector
---
> add ax, 31 ; first cluster = (stage2_cluster - 2) * sectors_per_cluster + start_sector
162c162
< mov ax, [kernel_cluster]
---
> mov ax, [stage2_cluster]
186c186
< mov [kernel_cluster], ax
---
> mov [stage2_cluster], ax
216c216
< mov si, msg_kernel_not_found
---
> mov si, msg_stage2_not_found
367,369c367,369
< msg_kernel_not_found: db 'KERNEL.BIN file not found!', ENDL, 0
< file_kernel_bin: db 'KERNEL BIN'
< kernel_cluster: dw 0
---
> msg_stage2_not_found: db 'STAGE2.BIN file not found!', ENDL, 0
> file_stage2_bin: db 'STAGE2 BIN'
> stage2_cluster: dw 0
代码如下:
3. stage2 : 将kernel中的main.asm和state1中的makefile 复制到stage2中,并进行相应的修改:
BUILD_DIR ?= build/
ASM ?=nasm
.PHONY: all clean
all: stage2
stage2: $(BUILD_DIR)/stage2.bin
$(BUILD_DIR)/stage2.bin:
$(ASM) main.asm -f bin -o $(BUILD_DIR)/stage2.bin
clean:
rm -f $$(BUILD_DIR)/stage2
4. 将part4的Makefile中的bootloader产生依赖修改为stage1, stage2, clean以及wcc,wlink编译指令(watcom)
原文:
#
# Bootloader
#
bootloader: $(BUILD_DIR)/bootloader.bin
$(BUILD_DIR)/bootloader.bin: always
$(ASM) $(SRC_DIR)/bootloader/boot.asm -f bin -o $(BUILD_DIR)/bootloader.bin
修改为:
bootloader: stage1 stage2
stage1: $(BU