08_实验七_拓展实验二

发布时间 2023-12-07 23:30:34作者: 彬彬zhidao

拓展实验2:在物理机上运行EOS操作系统

任务一:改进 EOS 内核引导过程,实现裸机从无文件系统的平坦软盘镜像引导

内核代码调整

将 EOS 内核引导过程调整为 U 盘引导后,就不再需要对内核进行 FAT 文件系统相关内容的初始化,将其注释掉,否则会因为初始化失败而无法进入到内核。需要将文件 ioinit.c的第 174 至第 226 行代码注释掉。

调整配置

因为本次任务是通过平坦镜像文件进行引导,因此需要调整项目配置,具体的操作步骤

如下:

(1)右键点击“项目管理器”中的项目根节点,选择“属性”,将“配置属性”中的“远程目标机”设置为“Bochs Debug”,这样就可以在启动时进行调试。

(2)将“配置属性”—》“常规”—》“调试前命令”中的内容清空。

(3)在“生成事件”—》“生成后事件”—》“命令行”中添加如下命令:

echo 正在制作引导软盘映像文件...

mkfloppy.exe "\((OutDir)\boot.bin" "\)(OutDir)\loader.bin" "$(TargetPath)" "Floppy.img"

命令的作用是调用写镜像工具 mkfloppy.exe 将二进制文件 boot.bin、loader.bin以及内核程序 kernel.dll 依次写入到镜像 Floppy.img 中。

(4)以上配置完成后点击“应用”按钮并关闭属性页。

启动 Bochs 调试

首先生成项目,OS Lab 会自动将 boot.bin,loader.bin,kernel.dll 这三个文件依次写到平坦镜像文件 Floppy.img。这样启动调试后,Bochs 会加载这个镜像。

生成项目成功后,按 F5 启动调试,这时可直接在 console 窗口中的光标闪烁处输入“c”后按下回车,直接继续执行程序,查看是否正常进入内核。

若继续执行后没有进入到 EOS 内核程序,则可在几个关键位置上添加断点进行调试,查看寄存器状态以及运行的指令,如断点 0x0000:0x7c00、0x0000:0x1000 处查看 boot 和loader 的运行过程。

添加代码

	; ######################################################
	; 在此处编辑代码,功能是:从镜像文件读600个扇区到物理内存0x10000处

    ; new
    ; begin

    mov ax, 0x1000 ;基址为 0x1000
    mov cx, 0x258 ;循环次数 600
    mov dx, 0x5 ;扇区值
LOOPREAD:
    push ax ;保存
    push cx ;保存
    push dx ;保存
    ;函数参数设置
    mov bx, 0 ;偏移值为 0
    push bx ;wOffset
    push ax ;wBase
    mov bx, 1 ;读 1 个扇区
    push bx ;wCount
    push dx ;wSector
    call ReadSector ;调用 ReadSector 函数
    ;函数结束
    pop dx ;恢复
	pop cx ;恢复
	pop ax ;恢复
    add ax, 0x20 ;基址增加 0x20
    inc dx ;增加扇区值
	loop LOOPREAD ;循环
    ; end

	
    ; ######################################################
	

还需要注释掉IOinit文件家里面的一段代码,指导书上是这样写的。

相关图片和调试结果

image-20231207220715142

image-20231207212806796

image-20231207222407288

暂存一些代码

md sdk
md sdk\inc
md sdk\bin
md sdk\bin\debug
copy eosdef.h sdk\inc\eosdef.h
copy error.h sdk\inc\error.h
copy eos.h sdk\inc\eos.h
copy "$(OutDir)\boot.bin" sdk\bin\debug\boot.bin
copy "$(OutDir)\loader.bin" sdk\bin\debug\loader.bin
copy "$(TargetPath)" "sdk\bin\debug\$(TargetFileName)"
copy "$(TargetDir)lib$(TargetName).a" "sdk\bin\debug\lib$(TargetName).a"

任务二:改进 EOS 内核引导过程,实现物理机从 U 盘引导加载 EOS 内核

修改和添加代码以及过程和结果的截图

首先修改配置

(1)右键点击“项目管理器”中的项目根节点,选择“属性”,将“配置属性”中的“远程目标机”设置为“Bochs Debug”,这样就可以在启动时进行调试。

(2)将“配置属性”中的“调试前命令”清空。

(3)在“生成事件”—》“生成后事件”—》“命令行”中添加如下命令:

echo 正在制作引导 U 盘映像文件...

mkimage.exe "$(OutDir)\boot.bin" "$(OutDir)\loader.bin" "$(TargetPath)" "Floppy.img"

命令的作用是调用写镜像工具 mkimage.exe 将二进制文件 boot.bin、loader.bin 以及内核程序 kernel.dll 依次写入到镜像 Floppy.img 中。

如上实验1:

image-20231207221534557

mempool.c 文件的 86 行、87 行注释,防止内存校验报错导致无法进入内核。

**ioinit.c 文件的第 174 至第 226 行代码注释,去掉初始化软驱的内容。 **

loader.asm文件夹中添加以下代码:

Start:
	;
	; 得到物理内存的大小
	call GetMemorySize
	mov dword [PhysicalMemorySize], eax
	
	; ######################################################
	; 在此处编辑代码,功能是:从镜像文件读600个扇区到物理内存0x10000处
	
    ; new
    ; begin
    mov cx, 0x258 ;循环次数 600
LOOPREAD:	
	mov	ah, 0x42
	mov	dl, 0x80
	mov	si, packet
	int 0x13

    ;以下是将地址数据结构中的起始LBA后移1块继续写入下一个扇区
	
	mov	ax, [bufferseg]
	mov	bx, bufferseg
	add	ax, 0x20
	mov	[bx], ax
	
	;将起始LBA加1,以读取下一个扇区
	mov	ax, [blockNum]
	mov	bx, blockNum
	add	ax, 1
	mov	[bx], ax
	loop LOOPREAD ;循环
    ; ends	
    ; ######################################################

	;
	; 检查内核映像的虚拟基址及映像大小是否符合约定,Loader 不支持内核重定位。

image-20231207224030126

image-20231207220715142