这一系列文章的标题是叫做:BosoKernel : une introduction a la programmation de systemes d'exploitation ,本想取个“靓”点的中文名,可惜标题原文实在太过质朴,且文章内容稍显单薄,遂放弃,后以“导论”二字引之(望各位看众贡献个更合适的名字)。
现在教习OS DIY的文章可谓满大街都是,那我为什么又把这篇文章从法国拐来?原因是最近学习法文,用来练手:)——因为是法文新手,望各位看众不吝指教一二。
这个内核位于软盘开始处的第二个扇区。为了将内核加载到内存,我们使用BIOS中断0x13。这个中断函数在"The Art of Assembly"(webster.cs.ucr.edu/page_asm/artofassembly/ch13/ch13-2.html#HEADING2-73)有详尽的解释。它可以从软盘复制一个或者多个扇区到内存。在本例中,我们拷贝了软盘的第二个扇区,即包含内核的扇区,到内存地址0x1000。变量KSIZE定义了要加载的扇区数量,使完整的内核正确地加载到内存。随后的部分所描述的这个早期的内核的代码相当简短。在我的机器上,生成的相应二进制文件是69个字节,因此我们可以仅设置KSIZE的值为1来拷贝一个单独的扇区。
; 加载内核
xor ax,ax
int 0x13
push es
mov ax,BASE
mov es,ax
mov bx,0
mov ah,2
mov al,KSIZE
mov ch,0
mov cl,2
mov dh,0
mov dl,[bootdrv]
int 0x13
pop es
代码分成一个引导扇区代码文件和一个内核代码文件。文件 UTIL.INC 仅仅是一种包含了函数'afficher'的函数库:
$ ls
UTIL.INC bootsect.asm kernel.asm
分别编译各个程序:
$ nasm -f bin -o bootsect bootsect.asm
$ nasm -f bin -o kernel kernel.asm
$ ls -l
total 14
-rw-r--r-- 1 am users 492 Jan 17 17:20 UTIL.INC
-rw-r--r-- 1 am users 512 Jan 19 18:16 bootsect
-rw-r--r-- 1 am users 715 Jan 17 17:22 bootsect.asm
-rw-r--r-- 1 am users 297 Jan 17 17:50 kernel.asm
-rw-r--r-- 1 am users 69 Jan 19 18:16 kernel
我们注意到引导扇区的二进制文件刚好512字节,而生成的内核二进制文件只有69字节。我们制作的软盘将内核放进了第二个扇区。用以下命令生成软盘映像:
$ cat bootsect kernel /dev/zero | dd of=floppy bs=512 count=2880
$ ls -l floppy
-rw-r--r-- 1 am users 1474117 Jan 19 18:27 floppy
; passage en modep
cli
lgdt [gdtptr] ; charge la gdt
mov eax,cr0
or ax,1
mov cr0,eax ; PE mis a 1 (CR0)
jmp next
next:
mov ax,0x10 ; segment de donne
mov ds,ax
mov fs,ax
mov gs,ax
mov es,ax
mov ss,ax
mov esp,0x9F000
jmp dword 0x8:0x1000 ; reinitialise le segment de code
;--------------------------------------------------------------------
bootdrv: db 0
msgDebut db "Chargement du kernel",13,10,0
;--------------------------------------------------------------------
gdt:
db 0,0,0,0,0,0,0,0
gdt_cs:
db 0xFF,0xFF,0x0,0x0,0x0,10011011b,11011111b,0x0
gdt_ds:
db 0xFF,0xFF,0x0,0x0,0x0,10010011b,11011111b,0x0
gdtend:
;--------------------------------------------------------------------
gdtptr:
dw 0 ; limite
dd 0 ; base
;--------------------------------------------------------------------
;; NOP jusqu'a 510
times 510-($-$$) db 144
dw 0xAA55