在上一篇文章中已实现了用boot加载loader,并执行loader,loader中的代码只是显示一个‘L’字符。在这里,我们要用loader加载kernel到内存。加载方法和用boot加载loader的方法一样,只是加载的文件名变了(由loader.bin改为kernel.bin),加载到内存的地址变了。
下面只给出loader.asm的源代码,该源代码是《自己动手写操作系统》上的,boot.asm的源代码请参见第26篇文章。
在这说一下loader.asm与boot.asm的少许不同。在loader.asm中要加载到的内存地址变了;少了清屏的部分;并且在DispStr函数中加了add ah,3; 标签的名字变了 ;加了一个关闭软驱马达的函数;其它的都是相同的。
loader.asm
org 0100h
;================================================================================================
BaseOfStack equ 0100h
BaseOfKernelFile equ 08000h ; KERNEL.BIN 被加载到的位置 ---- 段地址
OffsetOfKernelFile equ 0h ; KERNEL.BIN 被加载到的位置 ---- 偏移地址
;================================================================================================
jmp LABEL_START ; Start
; FAT12 磁盘的头
; ----------------------------------------------------------------------
BS_OEMName DB 'ForrestY' ; OEM String, 必须 8 个字节
BPB_BytsPerSec DW 512 ; 每扇区字节数
BPB_SecPerClus DB 1 ; 每簇多少扇区
BPB_RsvdSecCnt DW 1 ; Boot 记录占用多少扇区
BPB_NumFATs DB 2 ; 共有多少 FAT 表
BPB_RootEntCnt DW 224 ; 根目录文件数最大值
BPB_TotSec16 DW 2880 ; 逻辑扇区总数
BPB_Media DB 0xF0 ; 媒体描述符
BPB_FATSz16 DW 9 ; 每FAT扇区数
BPB_SecPerTrk DW 18 ; 每磁道扇区数
BPB_NumHeads DW 2 ; 磁头数(面数)
BPB_HiddSec DD 0 ; 隐藏扇区数
BPB_TotSec32 DD 0 ; 如果 wTotalSectorCount 是 0 由这个值记录扇区数
BS_DrvNum DB 0 ; 中断 13 的驱动器号
BS_Reserved1 DB 0 ; 未使用
BS_BootSig DB 29h ; 扩展引导标记 (29h)
BS_VolID DD 0 ; 卷序列号
BS_VolLab DB 'Tinix0.01 '; 卷标, 必须 11 个字节
BS_FileSysType DB 'FAT12 ' ; 文件系统类型, 必须 8个字节
;---