bootasm.S是bootloader(bootasm.S和bootmain.c)其中之一:
.set PROT_MODE_CSEG, 0x08 //kernel code segment selector
.set PROT_MODE_DSEG , 0x10 //kernel data segment selector
.set CR0_PE_ON , 0x1 //protected mode enable flag
.set SMAP, 0x534d4150
.globl start
start:
.code16
cli //interruptted 禁止中断
cld
xorw %ax,%ax
movw %ax,%ds
movw %ax,%es
movw %ax,%ss
//A20is booted; this is compablited x86
//wait for not busy
seta20.1
inb $0x64,%al
testb $0x2,%al
jnz seta20.1
//0xd1==>port 0x64
movb $0xd1,%al
outb %al,$0x64
//wait for not busy
seta20.2
inb $0x60,%al
testb $0x2,%al
jnz seta20.2
//0xdf ==>port 0x60
movb $0xdf.%al
outb %al,$0x60
//bios
//probe_memory:
movl $0,0x8000 //在内存0x8000处,赋值0,用于计数
xorl %ebx,%ebx //初始化ebx
movw $0x8004,%di //给Es:di赋值为0x8004 (指向的地址是中断返回有关内存段的信息数据内容的起始地址)
start_probe: //循环对内存的探测,所得的内存段的信息
movl $0xE820,%eax //给eax 赋值E820
movl $20,%ecx //给ecx 赋值20个字节
movl $SMAP,%edx //smap赋值给edx 把它设置为0x0534D4150
int $0x15 //15号中断
jnc cont //如果carry的第一位的值为1
movw $12345,0x8000//在0x8000处设结束标志
jmp finish_probe
cont:
addw $20,%di //di所指的地址处增加20个字节的偏移
incl 0x8000 //
cmpl $0,%ebx //这里ebx的值是int 15h 的中断获得的信息赋值给ebx
jnz start_probe
finish_probe: //
lgdt gdtdesc
movl %cr0, %eax
orl $CRO_PE_ON,%eax
movl %eax, %cr0
ljmp $PROT_MODE_CSEG,$protcseg
.code32
protcseg:
#Set up the protected-mode data segment registers
movw $PROT_MODE_DSEG,%ax //our data segment selector
movw %ax ,%ds //->DS:Data Segment
movw %ax,%es //->ES:Extra Segment
movw %ax,%fs //->FS
movw %ax,%gs //->GS
movw %ax,%ss //->SS:stack
//Set up the stack pointer and call into c
movl $start ,%esp
call bootmain
//if bootmain return ,loop
spin:
jmp spin
//bootstrap GDT
.p2align 2
alignment
gdt:
SEG_NULLASM # null seg
SEG_ASM(STA_X|STA_R, 0x0, 0xffffffff) # code seg
SEG_ASM(STA_W, 0x0, 0xffffffff) # data seg
gdtdesc:
.word 0x17 # sizeof(gdt) - 1
.long gdt # address gdt