C语言-编程技巧-Linux内核原代码head.s部分注释

/*

                 * head.s contains the 32-bit startup code.

                 *

                 * NOTE!!! Startup happens at absolute address 0x00000000, which is also where

   * the page directory will exist. The startup code will be overwritten by

   * the page directory.

   */

   .text

   .globl _idt,_gdt,_pg_dir

   _pg_dir:

   startup_32:

   movl $0x10,陎 @@ds,es,fs,gs指向内核数据段

   mov %ax,%ds

   mov %ax,%es

   mov %ax,%fs

   mov %ax,%gs

   lss _stack_start,%esp @@ds送ss esp 指向stack_start (在sched.c定义)

   @@进入保护模式的堆栈段的第一次变化,很奇怪

   @@为什么堆栈段也可正向增涨?

   call setup_idt

   call setup_gdt

   movl $0x10,陎 # reload all the segment registers

   mov %ax,%ds # after changing gdt. CS was already

   mov %ax,%es # reloaded in 'setup_gdt' @@ 有reload??

   mov %ax,%fs

   mov %ax,%gs

   lss _stack_start,%esp

   xorl 陎,陎

   1: incl 陎 # check that A20 really IS enabled

   movl 陎,0x000000

   cmpl 陎,0x100000 @@这是怎么测的 0x100000为什么值,

   @@明白,a20 not

   enable,0x000000就是0x100000

   je 1b

   movl %cr0,陎 # check math chip

   andl $0x80000011,陎 # Save PG,ET,PE

   testl $0x10,陎

   jne 1f # ET is set - 387 is present

   orl $4,陎 # else set emulate bit

   1: movl 陎,%cr0

   jmp after_page_s @@注意,用jmp 不call,不返回

   /*

   * setup_idt

   *

   * sets up a idt with 256 enies pointing to

   * ignore_int, interrupt gates. It then loads

   * idt. Everything that wants to install itself

   * in the idt- may do so themselves. Interrupts

   * are enabled elsewhere, when we can be relatively

   * sure everything is ok. This routine will be over-

   * written by the page s.

   */

   setup_idt:

   lea ignore_int,韝

   movl $0x00080000,陎

   movw %dx,%ax /* selector = 0x0008 = cs */

   movw $0x8E00,%dx /* interrupt gate - dpl=0, present */

   @@ ignore_int 低16ax 高16edx高字



@@ 8e00dx 8eax高字

   lea _idt,韎

   mov $256,靫

   rp_sidt:

   movl 陎,(韎)

   movl 韝,4(韎)

   addl $8,韎

   dec 靫

   jne rp_sidt

   lidt idt_descr

   ret



/*

   * setup_gdt

   *

   * This routines sets up a new gdt and loads it.

   * Only two enies are currently built, the same

   * ones that were built in init.s. The routine

   * is VERY complicated at two whole lines, so this

   * rather long comment is certainly needed :-).

   * This routine will beoverwritten by the page s.

   */

   setup_gdt:

   lgdt gdt_descr

   ret @@跳到main函数



.org 0x1000

   pg0:



.org 0x2000

   pg1:



.org 0x3000

   pg2: # This is not used yet, but if you

   # want to expand past 8 Mb, you'll have

   # to use it.



.org 0x4000

   after_page_s:

   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 @@再jmp

   L6:

   jmp L6 # main should never return here, but

   # just in case, we know what happens.



/* This is the default interrupt "handler" :-) */

   .align 2

   ignore_int:

   incb 0xb8000 160 # put something on the screen

   movb $2,0xb8000 161 # so that we know something

   iret # happened

  




/*

   * Setup_paging

   *

   * This routine sets up paging by setting the page bit

   * in cr0. The page s are set up, identity-mapping

   * the first 8MB. The pager assumes that no illegal

   * addresses are produced (ie >4Mb on a 4Mb machine).

   *

   * NOTE! Although all physical memory should be identity

   * mapped by this routine, only the kernel page functions

   * use the >1Mb addresses directly. All "normal" functions

   * use just the lower 1Mb, or the local data space, which

   * will be mapped to some other place - mm keeps ack of

   * that.

   *

   * For those with more memory than 8 Mb - tough luck. I've

   * not got it, why should you :-) The source is here. Change

   * it. (Seriously - it shouldn't be too difficult. Mostly

   * change some constants etc. I left it at 8Mb, as my machine

   * even cannot be extended past that (ok, but it was cheap :-)

   * I've ied to show which constants to change by having

   * some kind of marker at them (search for "8Mb"), but I





分页: [1] [2]




  • 上一篇: C语言-编程技巧-Linux 应用程序如何处理当前运行环境的环境变量