linux内核学习(13)我们开始慢慢地往上爬...(下)

# 下面先设置几个后面可能会用的着的中断向量
.macro    set_early_handler handler,trapno
    lea /handler,%edx
    movl $(__KERNEL_CS << 16),%eax
    movw %dx,%ax
    movw $0x8E00,%dx    /* interrupt gate - dpl=0, present */
    lea idt_table,%edi
    movl %eax,8*/trapno(%edi)
    movl %edx,8*/trapno+4(%edi)
.endm

# 宏描述,类似C里的define
    set_early_handler handler=early_divide_err,trapno=0
    set_early_handler handler=early_illegal_opcode,trapno=6
    set_early_handler handler=early_protection_fault,trapno=13
    set_early_handler handler=early_page_fault,trapno=14

    ret
# 对应的中断处理程序
early_divide_err:
    xor %edx,%edx
    pushl $0    /* fake errcode */
    jmp early_fault

early_illegal_opcode:
    movl $6,%edx
    pushl $0    /* fake errcode */
    jmp early_fault

early_protection_fault:
    movl $13,%edx
    jmp early_fault

early_page_fault:
    movl $14,%edx
    jmp early_fault

early_fault:
    cld     /*di,si ++*/
#ifdef CONFIG_PRINTK
    pusha
    movl $(__KERNEL_DS),%eax
    movl %eax,%ds
    movl %eax,%es
    cmpl $2,early_recursion_flag
    je hlt_loop
    incl early_recursion_flag
    movl %cr2,%eax
    pushl %eax
    pushl %edx        /* trapno */
    pushl $fault_msg
    call printk
#endif
    call dump_stack
hlt_loop:
    hlt
    jmp hlt_loop

/* This is the default interrupt "handler" :-) */
    ALIGN
# 这就是那个默认中断处理程序
ignore_int:
    cld
#ifdef CONFIG_PRINTK
    pushl %eax
    pushl %ecx
    pushl %edx
    pushl %es
    pushl %ds
    movl $(__KERNEL_DS),%eax
    movl %eax,%ds
    movl %eax,%es
    cmpl $2,early_recursion_flag
    je hlt_loop
    incl early_recursion_flag
    pushl 16(%esp)
    pushl 24(%esp)
    pushl 32(%esp)
    pushl 40(%esp)
    pushl $int_msg
    call printk

    call dump_stack

    addl $(5*4),%esp
    popl %ds
    popl %es
    popl %edx
    popl %ecx
    popl %eax
#endif
    iret

    __REFDATA
.align 4
# 看到没,之前那个跳转就是这里设置的这个,my name is "i386_start_kernel"。
ENTRY(initial_code)
    .long i386_start_kernel
ENTRY(initial_page_table)
    .long pa(swapper_pg_dir)

/*
 * BSS section
 */
# bss段
__PAGE_ALIGNED_BSS
    .align PAGE_SIZE_asm
#ifdef CONFIG_X86_PAE
swapper_pg_pmd:
    .fill 1024*KPMDS,4,0
#else
# 这就是那个全局页目录共4k,1024项,每项4B
ENTRY(swapper_pg_dir)           /*a page for 4k*/
    .fill 1024,4,0
#endif
# 这个是设置的最后那个全局页目录项的页表地址
swapper_pg_fixmap:              /*a page for 4k*/
    .fill 1024,4,0
#ifdef CONFIG_X86_TRAMPOLINE
ENTRY(trampoline_pg_dir)
    .fill 1024,4,0
#endif
ENTRY(empty_zero_page)
    .fill 4096,1,0

/*
 * This starts the data section.
 */
# 注意这里我们假设没有开启PAE物理地址扩展的
#ifdef CONFIG_X86_PAE   /*if physical address extend 64G*/
__PAGE_ALIGNED_DATA
    /* Page-aligned for the benefit of paravirt? */
    .align PAGE_SIZE_asm
ENTRY(swapper_pg_dir)
    .long    pa(swapper_pg_pmd+PGD_IDENT_ATTR),0    /* low identity map */
# if KPMDS == 3
    .long    pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
    .long    pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
    .long    pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x2000),0
# elif KPMDS == 2
    .long    0,0
    .long    pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
    .long    pa(swapper_pg_pmd+PGD_IDENT_ATTR+0x1000),0
# elif KPMDS == 1
    .long    0,0
    .long    0,0
    .long    pa(swapper_pg_pmd+PGD_IDENT_ATTR),0
# else
#  error "Kernel PMDs should be 1, 2 or 3"
# endif
    .align PAGE_SIZE_asm        /* needs to be page-sized too */
#endif

.data
# 栈的存放处
ENTRY(stack_start)
    .long init_thread_union+THREAD_SIZE
    .long __BOOT_DS

ready:    .byte 0

early_recursion_flag:
    .long 0

int_msg:
    .....  .... # 省略

# 这个我们好像不是感兴趣
#include "../../x86/xen/xen-head.S"

/*
 * The IDT and GDT 'descriptors' are a strange 48-bit object
 * only used by the lidt and lgdt instructions. They are not
 * like usual segment descriptors - they consist of a 16-bit
 * segment size, and 32-bit linear address value:
 */

.globl boot_gdt_descr   # 很久以前设置的GDT了
.globl idt_descr             # IDT中断向量表描述符

    ALIGN
# early boot GDT descriptor (must use 1:1 address mapping)
    .word 0                # 32 bit align gdt_desc.address
boot_gdt_descr:
    .word __BOOT_DS+7
    .long boot_gdt - __PAGE_OFFSET

    .word 0                # 32-bit align idt_desc.address
idt_descr:
    .word IDT_ENTRIES*8-1        # idt contains 256 entries
    .long idt_table

# boot GDT descriptor (later on used by CPU#0):
    .word 0                # 32 bit align gdt_desc.address
ENTRY(early_gdt_descr)
    .word GDT_ENTRIES*8-1
    .long gdt_page            /* Overwritten for secondary CPUs */

/*
 * The boot_gdt must mirror the equivalent in setup.S and is
 * used only for booting.
 */
    .align L1_CACHE_BYTES
ENTRY(boot_gdt)
    .fill GDT_ENTRY_BOOT_CS,8,0
    .quad 0x00cf9a000000ffff    /* kernel 4GB code at 0x00000000 */
    .quad 0x00cf92000000ffff    /* kernel 4GB data at 0x00000000 */

我的妈呀!看看这段程序,长得跟什么似的,其实真正我们关心的也没几个,其实即使是我们关心的,也不会成为我们的后面的焦点,因为这些还太底层了,我们不需要,呵呵!还得往上爬点,到了,我们自然就会流露处欣喜的表情。如果你也认真分析了,而且一直坚持到现在,估计后面的分析会比较好了,至少说遇到不懂的问题,你不会放弃,当然这里指的“不懂的问题”是我们所关心的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值