linux启动源码,读linux启动源代码的总结

读之前先带着几个问题:

一般来讲linux内核启动过程分为三个阶段,那么这三个阶段各自都完成了什么任务呢,或者说各自为下一个阶段准备了怎样的执行环境呢?

本阶段是如何准备好的下一阶段的执行环境呢?

首先详细谈谈内核解压缩后加载到物理内存0x100000处时的执行环境,此时呢代码已经运行在32位保护模式下,是通过指令ljmp 0x100000跳转到并开始执行的,对应于/linux/arch/kernel/head.s文件中的start_32,此时还处于段式寻址方式,还并未启动分页寻址,ip=0x100000;即ip就代表了指令的物理地址,因为此时段地址起始为零;另外一点需要注意的是内核再被编译的时候符号地址相对于被加载的物理地址都有一个偏移即PAGE_OFFSET,这个常数在i386体系结构下被定义为0xc000000,举个例子若swapper_pg_dir被加载到的实际物理内存地址是0x11000那么其被编译后的符号地址就是0xc011000。在未启动分页机制之前如果想要引用某个符号地址必须把它转化成为相应的实际物理地址。

那么start_32完成了什么功能呢主要,主要是启动了页面机制为下一步初始化作进一步准备,但是只是把内核的前八兆内容作了映射。最后跳转到start_kernel这个函数执行,start_kernel执行完后,这就是一般的第二和第三两个阶段。当start_kernel执行完后物理内存的管理机制已建立完毕,进程的初始化也完成了,第一个进程init也得到了创建。

整个过程中物理内存管理机制的创建过程经过了两步,第一步是建立bootmem allocator,第二步建立伙伴分配系统。整个过程思想就是白手起家缺什么数据就根据当前的内存信息捏造出来,最后完成两个分配器的交接。

另一点需要注意的是内核的启动代码其实也有其运行的进程上下文,这个current可由ss推算出来,也就是get current宏。这个ss其实是在start_32阶段就被精心设置好了的,  其实内核已经准备好了一个init_task_union 数据结构,而最后ss就会指向与这个task的共享的页面。

个人认为linux内核中最重要的基础设施就是内存分配和进程的管理了,当这两个基础设施被初始化后,实现其他的机制的初始化也不在话下了。这段启动代码中有很多值得品味的地方,例如刚开始启动分页机制时同时把前八兆内容映射到了用户空间的低八兆的空间,这是个很巧妙的设置。

另一个收获就是当读完这段代码后就会对高端内存的问题有一个更加深入的理解,让我试着来解释下这个问题。我们知道在一般对于32位寻址的i386,linux把整个4g的虚拟空间分成1G和3G的结构,那么内核怎么能在自己1G的虚拟内存区间访问到整个4G的物理内存呢?linux规定内核直接线性映射的物理空间范围在0-896兆之间,超过了这个范围的物理地址就被称作是高端内存,当物理内存小于896时就不存在高端内存的问题了。那么怎么解决这个问题呢?解决方案的基本思路有以下几个

增加内核空间的大小,例如减小PAGE_OFFSET,把4G的虚拟内存空间分割成2G,2G的结构;另一种就是当前内核普遍采用的方法,把896-1024这128兆虚拟空间在不同的时候调整对应到不同的物理页面,这就是动态映射,而这个区间又可以分为几种不同的映射方法,永久性映射动态映射等。

内核是一个充满神秘和智慧的星空,当你揭开一个个秘密是它那么的触手可及。。。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值