dedecms织梦内容管理系统    
首页 | java | C/C++ | PHP | 操作系统 | ajax | 脚本编程 | 安全技术 | 本站下载页 | flex | CRM | 专题 | QQ群 | 测试中心 | 会员中心 | 积分规则
  当前位置:主页>操作系统>linux>文章内容
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,%eax @@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,%eax # 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 %eax,%eax
   1: incl %eax # check that A20 really IS enabled
   movl %eax,0x000000
   cmpl %eax,0x100000 @@这是怎么测的 0x100000为什么值,
   @@明白,a20 not
   enable,0x000000就是0x100000
   je 1b
   movl %cr0,%eax # check math chip
   andl $0x80000011,%eax # Save PG,ET,PE
   testl $0x10,%eax
   jne 1f # ET is set - 387 is present
   orl $4,%eax # else set emulate bit
   1: movl %eax,%cr0
   jmp after_page_tables @@注意,用jmp 不call,不返回
   /*
   * setup_idt
   *
   * sets up a idt with 256 entries pointing to
   * ignore_int, interrupt gates. It then loads
   * idt. Everything that wants to install itself
   * in the idt-table 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 tables.
   */
   setup_idt:
   lea ignore_int,%edx
   movl $0x00080000,%eax
   movw %dx,%ax /* selector = 0x0008 = cs */
   movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
   @@ ignore_int 低16-->ax 高16-->edx高字

@@ 8e00-->dx 8-->eax高字
   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
   *
   * This routines sets up a new gdt and loads it.
   * Only two entries 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 tables.
   */
   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_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 @@再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
   mo $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 tables 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 track 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 tried to show which constants to change by having
   * some kind of marker at them (search for "8Mb"), but I
   * won't guarantee that's all :-( )
   */
   .align 2
   setup_paging:
   movl $1024*3,%ecx @@pg_dir pg_table 清零
   xorl %eax,%eax
   xorl %edi,%edi /* pg_dir is at 0x000 */
   cld;rep;stosl
   movl $pg0+7,_pg_dir /* set present bit/user r/w */
   movl $pg1+7,_pg_dir+4 /* --------- " " --------- */
   movl $pg1+4092,%edi
   movl $0x7ff007,%eax /* 8Mb - 4096 + 7 (r/w user,p) */
   std
   1: stosl /* fill pages backwards - more efficient :-) */
   subl $0x1000,%eax
   jge 1b @@ greater or equal
   xorl %eax,%eax /* pg_dir is at 0x0000 */
   movl %eax,%cr3 /* cr3 - page directory start */
   movl %cr0,%eax
   orl $0x80000000,%eax
   movl %eax,%cr0 /* set paging (PG) bit */
   ret /* this also flushes prefetch-queue */

@@页目录pg_dir=0 仅两项(8M),
   @@pg1,pg0页表逆向填充,pg0的首页仍为零
   @@这样映射,线性地址=物理地址

.align 2
   .word 0
   idt_descr:
   .word 256*8-1 # idt contains 256 entries
   .long _idt
   .align 2
   .word 0
   gdt_descr:
   .word 256*8-1 # so does gdt (not that that's any @@和前面head.S差一??
   .long _gdt # magic number, but it works for me :^)

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

_gdt: .quad 0x0000000000000000 /* NULL descriptor */
   .quad 0x00c09a00000007ff /* 8Mb */
   .quad 0x00c09200000007ff /* 8Mb */
   .quad 0x0000000000000000 /* TEMPORARY - don't use */
   .fill 252,8,0 /* space for LDT's and TSS's etc */
   @@内核 逻辑地址(不含段寄存器)=线性地址

 

 

上一篇:linux 内核原代码 sched.c 的注释   下一篇:Linux 应用程序如何处理当前运行环境的环境变量
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
用户名: 新注册) 密码: 匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论
  热点文章
·Linux常用基本命令及应用技巧
·写得蛮好的linux学习笔记
·学会在Linux下对硬盘分区
·找回Redhat的超级用户密码
·Linux下C语言编程
·GDB教程
·Cron服务配置详解
·Linux与Unix二大操作系统编程的
·Linux 2.6 内核的嵌入式系统应用
·Linux和Windows系统调用的比较
·vim命令(一)
·vim 命令(二)
  相关文章
·linux 内核原代码 sched.c 的注
·Linux 应用程序如何处理当前运行
·编写 Linux 操作系统下的设备驱
·Linux 内核原代码 boot.s 部分的
·Linux 下面截获系统调用
·Linux 内核原代码 init/main 的
·Linux 下面使用 mtrace 来检查一
·Linux 内核模块和驱动程序的编写
·Linux 和 Unix 安全编程:环境变
·Linux 最新稳定内核 2.4.x 的网
·Linux 守护进程的编程方法
·为 Linux 应用程序编写 DLL
  相关信息
copy right @ 百家拳软件项目研究室 2007 辽ICP备07011763