LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2246|回复: 1

head.S分析

[复制链接]
发表于 2003-4-15 22:13:27 | 显示全部楼层 |阅读模式
因为setup.S1最后的为一条转跳指令,跳到内核第一条指令并开始执行。指令中指向的是内存中的绝对地址,我们无法依此判断转跳到了head.S。但是我们可以通过Makefile简单的确定head.S位于内核的前端。
在arch/i386 的 Makefile 中定义了
        HEAD := arch/i386/kernel/head.o

而在linux总的Makefile中由这样的语句
    include arch/$(ARCH)/Makefile
说明HEAD定义在该文件中有效

    然后由如下语句:

vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
  $(ARCHIVES) \
  $(FILESYSTEMS) \
  $(DRIVERS) \
  $(LIBS) -o vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System.map

从这个依赖关系我们可以获得大量的信息

1>$(HEAD)即head.o的确第一个被连接到核心中

2>所有内核中支持的文件系统全部编译到$(FILESYSTEMS)即fs/filesystems.a中
  所有内核中支持的网络协议全部编译到net.a中
  所有内核中支持的SCSI驱动全部编译到scsi.a中
  ...................
  原来内核也不过是一堆库文件和目标文件的集合罢了,有兴趣对内核减肥的同学,
  可以好好比较一下看究竟是那个部分占用了空间。

3>System.map中包含了所有的内核输出的函数,我们在编写内核模块的时候
  可以调用的系统函数大概就这些了。


好了,消除了心中的疑问,我们可以仔细分析head.s了。

Head.S分析

1 首先将ds,es,fs,gs指向系统数据段KERNEL_DS
  KERNEL_DS 在asm/segment.h中定义,表示全局描述符表中
  中的第三项。
  注意:该此时生效的全局描述符表并不是在head.s中定义的
        而仍然是在setup.S中定义的。

2 数据段全部清空。

3 setup_idt为一段子程序,将中断向量表全部指向ignore_int函数
  该函数打印出:unknown interrupt
  当然这样的中断处理函数什么也干不了。

4 察看数据线A20是否有效,否则循环等待。
  地址线A20是x86的历史遗留问题,决定是否能访问1M以上内存。

5 拷贝启动参数到0x5000页的前半页,而将setup.s取出的bios参数
  放到后半页。

6 检查CPU类型
  @#$#%$^*@^?(^%#$%!#!@?谁知道干了什么?

7 初始化页表,只初始化最初几页。

  1>将swapper_pg_dir(0x2000)和pg0(0x3000)清空
    swapper_pg_dir作为整个系统的页目录

  2>将pg0作为第一个页表,将其地址赋到swapper_pg_dir的第一个32
    位字中。

  3>同时将该页表项也赋给swapper_pg_dir的第3072个入口,表示虚拟地址
    0xc0000000也指向pg0。

  4>将pg0这个页表填满指向内存前4M

  5>进入分页方式
    注意:以前虽然在在保护模式但没有启用分页。

    --------------------
    |  swapper_pg_dir  |       -----------
    |                  |-------| pg0     |----------内存前4M
    |                  |       -----------
    |                  |
    --------------------
8 装入新的gdt和ldt表。

9 刷新段寄存器ds,es,fs,gs

10 使用系统堆栈,即预留的0x6000页面

11 执行start_kernel函数,这个函数是第一个C编制的
   函数,内核又有了一个新的开始。1

注:我在linux0.01版本中没有看到setup.s文件,请问是不是因为以当时内核的大小还用不着压缩,所
以没有解压缩模块,但硬件信息的检测与初始化,在哪里进行呢?希望高手解答。
 楼主| 发表于 2003-4-16 00:11:06 | 显示全部楼层
我知道了,原来以前版本的内核没有这么复杂,根本没有考虑到压缩
setup.s的内容全在boot.s(也就是bootsect.s)实现了。好了,明
天继续进步!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表