经过折腾了整整一篇的BIOS,总算可以跑linux 0.11内核源码了。第一个执行的是bootsect.s,如果现在你还没有下载linux 0.11的源码就赶紧去下载。如果自己懒得找,可以参见我下一篇文章,那里把所有流程都理了一遍:https://blog.youkuaiyun.com/u013471946/article/details/115436491
1.2.2加载第二部分内核代码——setup模块
坑一: 书1.2.2贴出了bootsect.s开头内容,又是文字又是画图说明其含义,然而让人看得很累,因为他们没有像我这样给源码标注一下^_^:
(SETUP程序有几个扇区)SETUPLEN = 4 ! nr of setup-sectors
(BIOS把启动扇区内容先扔这)BOOTSEG = 0x07c0 ! original address of boot-sector
(启动扇区内容搬的新家)INITSEG = 0x9000 ! we move boot here - out of the way
(SETUP程序被扔哪了)SETUPSEG = 0x9020 ! setup starts here
(kernel内核扔这)SYSSEG = 0x1000 ! system loaded at 0x10000 (65536).
(kernel内核尾巴)ENDSEG = SYSSEG + SYSSIZE ! where to stop loading
当然,你可以用自己的语言,用铅笔在书上标注出各参数的含义,不然初学者看着真够累。
好接下来上bootsect.s的执行代码部分:
entry start
start:
mov ax,#BOOTSEG
mov ds,ax
mov ax,#INITSEG
mov es,ax
mov cx,#256
sub si,si
sub di,di
rep
movw
jmpi go,INITSEG
go: mov ax,cs
mov ds,ax
mov es,ax
! put stack at 0x9ff00.
mov ss,ax
mov sp,#0xFF00 ! arbitrary value >>512
坑二:上完代码,书上在讲什么ds、si拼成0x07C00?es、di也拼成了0x90000?cx又是啥玩意?看来作者没打算帮你普及各寄存器的基础知识。来,先回顾下之前我写的关于汇编基础入门:
由于计算机经历从16位机扩展到32位机的过程,intel沿用的以前的标准,即将16位(即2字节)定义为“字”,32位(4字节)定义为“双字”。而8位仍成为“字节”,用符号表示如下:
字:w 16位
双字:l 32位
字节:b 8位
单精度:s 8位
双精度:l 32位
下面是整数寄存器示意图:
31 15 8 7 0
%eax %ax |
|
||
%ecx %cx |
|
||
%edx %dx |
|
||
%ebx %bx |
|
||
%esi %si | |||
%edi %di | |||
%esp %sp | 栈指针 | ||
%ebp %bp | 帧指针 |