1.3:系统启动-第三阶段head.s

1:功能

setup在获取一些硬件参数,启动保护模式后,就会进入head.s代码中执行。
head.s中会进行:
1)设置中断表
2)设置GDT表
3)设置页表
4)跳转到main函数

2:代码实现

2.1 设置中断表

重新设置中断描述符idt,共256项,并使各个表项均指向一个只报错误的哑中断程序

setup_idt:
        lea ignore_int,%edx
        movl $0x00080000,%eax
        movw %dx,%ax            /* selector = 0x0008 = cs */
        movw $0x8E00,%dx        /* interrupt gate - dpl=0, present */

        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

2.2 设置GDT表

虽然在setup中设置了gdt表,但是是为了临时执行“jumpi 0,8”,现在需要重新建立

setup_gdt:
        lgdt gdt_descr
        ret
gdt_descr:
        .word 256*8-1           # so does gdt (not that that's any
        .long gdt               # magic number, but it works for me :^)

        .align 8
idt:    .fill 256,8,0           # idt is uninitialized

gdt:    .quad 0x0000000000000000        /* NULL descriptor */
        .quad 0x00c09a0000000fff        /* 16Mb */
        .quad 0x00c0920000000fff        /* 16Mb */
        .quad 0x0000000000000000        /* TEMPORARY - don't use */
        .fill 252,8,0                   /* space for LDT's and TSS's etc */

2.3 设置页表

.align 2
setup_paging:
        movl $1024*5,%ecx               /* 5 pages - pg_dir+4 page tables */
..................

2.4 跳转到main函数

pushl $L6作为模拟调用main.c程序时返回地址作为入栈操作,如果main真的退出是,就会进入死循环
将main.c压人栈中,这样分页处理介绍后执行ret,就会进入main函数

after_page_tables:
        pushl $0                # These are the parameters to main :-)
        pushl $0
        pushl $0
        pushl $L6               # return address for main, if it decides to.
        pushl $main
        jmp setup_paging
L6:
        jmp L6 

3:总结

head.s执行结束后,整个内存映像如下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值