head.s 通过编译链接的处理,同时被 boot.s 加载到保护模式零地址开始运行,在最后会调用 main 函数。
代码:
.code32 .text .globl idt, gdt, pg_dir, startup_32 pg_dir: startup_32: movl $0x10,%eax mov %ax,%ds mov %ax,%es mov %ax,%fs mov %ax,%gs lss stack_start,%esp call setup_idt call setup_gdt movl $0x10,%eax mov %ax,%ds mov %ax,%es mov %ax,%fs mov %ax,%gs lss stack_start,%esp xorl %eax,%eax 1: incl %eax movl %eax,0x000000 cmpl %eax,0x100000 je 1b movl %cr0,%eax andl $0x80000011,%eax testl $0x10,%eax jne 1f orl $4,%eax 1: movl %eax,%cr0 jmp after_page_tables setup_idt: lea ignore_int,%edx movl $0x00080000,%eax movw %dx,%ax movw $0x8E00,%dx lea idt,%edi mov $256,%ecx rp_sidt: movl %eax,(%edi) movl %edx,4(%edi) addl $8,%edi dec %ecx jne rp_sidt lidt idt_descr ret setup_gdt: lgdt gdt_descr # 设置全局描述附表 ret .org 0x1000 # 设置起始地址 pg0: / .org 0x2000 pg1: .org 0x3000 pg2: .org 0x4000 after_page_tables: pushl $0 pushl $0 pushl $0 pushl $L6 pushl $main jmp setup_paging L6: jmp L6 .align 2 ignore_int: incb 0xb8000+160 movb $2,0xb8000+161 iret .align 2 setup_paging: movl $1024*3,%ecx xorl %eax,%eax xorl %edi,%edi cld;rep;stosl movl $pg0+7,pg_dir movl $pg1+7,pg_dir+4 movl $pg1+4092,%edi movl $0x7ff007,%eax std 1: stosl subl $0x1000,%eax jge 1b xorl %eax,%eax movl %eax,%cr3 movl %cr0,%eax orl $0x80000000,%eax movl %eax,%cr0 ret .align 2 .word 0 idt_descr: .word 256*8-1 .long idt .align 2 .word 0 gdt_descr: .word 256*8-1 .long gdt .align 8 idt: .fill 256,8,0 gdt: .quad 0x0000000000000000 .quad 0x00c09a00000007ff .quad 0x00c09200000007ff .quad 0x0000000000000000 .fill 252,8,0