在老版本的内核源码中可以看到bootsect.S的引导扇区代码和setup.S辅助程序代码,BIOS把引导扇区读到0x7c00,这段代码把自身搬到0x90000处,把setup.S映像读到0x9200处
在新版本的内核中,把bootsect.S和setup.S合并到header.S中去了,并切不再负责系统的引导,而需要其他boot loader(比如grub).
header.S部分代码:
bootsect_start:
# Normalize the start address
ljmp $BOOTSEG, $start2
start2:
movw %cs, %ax
...
# Allow the user to press a key, then reboot
xorw %ax, %ax
int $0x16
int $0x19
# int 0x19 should never return. In case it does anyway,
# invoke the BIOS reset code...
ljmp $0xf000,$0xfff0
.section ".bsdata", "a"
bugger_off_msg:
.ascii "Direct booting from floppy is no longer supported./r/n"
.ascii "Please use a boot loader program instead./r/n"
.ascii "/n"
.ascii "Remove disk and press any key to reboot . . ./r/n"
.byte 0
...
section ".header", "a"
.globl hdr
hdr:
...
boot_flag: .word 0xAA55
# offset 512, entry point
从这段代码可以看出只是显示Direct booting from floppy is no longer supported...的出错信息,如果BIOS直接把他加载到0x7c00将不能引导系统启动.注意最后的注释#offset512,entry point,从文件开始到最后一行boot_flag:word0xAA55并没有512字节,看看链接脚本setup.ld就知道了:
SECTIONS
{
. = 0;
.bstext
: { *(.bstext) }
.bsdata
: { *(.bsdata) }
. = 497;
.header
: { *(.header) }
.entrytext
: { *(.entrytext) }
....
通过.=497指定header的起始地址为0x1F1(497),这样到0xAA55整好512字节.
内存分布(Documentation/x86/i386/boot.txt)
~ ~
| Protected-mode kernel |
100000 +---------------------------------+
| I/O memory hole
|
0A0000
+--------------------------------+
| Reserved for BIOS
|
Leave as much as possible unused
~ ~
| Command line |
(Can also be below the X+10000 mark)
X+10000
+--------------------------------+
| Stack/heap
|
For use by the kernel real-mode code.
X+08000
+--------------------------------+
| Kernel setup
|
The kernel real-mode code.
| Kernel boot sector
|
The kernel legacy boot sector.
X +--------------------------------+
| Boot loader
|
<- Boot sector entry point 0000:7C00
001000
+--------------------------------+
|Reserved for MBR/BIOS|
000800
+--------------------------------+
| Typically used by MBR |
000600
+--------------------------------+
| BIOS use only
|
000000
+--------------------------------+
... where the address X is as low as the design of the boot loader
permits.
Boot loader把该映像加载到X处后,修改DS寄存器的值为X,跳转到DS:0x200把控制权交给_start:,代码如下:
//header.S
...
_start:
# Explicitly enter this as bytes, or the assembler
# tries to generate a 3-byte jump here, which causes
# everything else to push off to the wrong offset.
.byte
0xeb
# short (2-byte) jump
.byte
start_of_setup-1f
...
这是一条跳转指令,跳转到 start_of_setup处