Linux kernel 分析之六:内核启动-开启页面映射

本文详细介绍了Linux内核启动过程中开启页面映射的步骤,包括创建页目录、页表的初始化,以及如何将内核代码和数据映射到虚拟地址空间。通过映射,使得内核可以直接引用所有变量并为启动swapper进程做准备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


在setup的帮助下,我们顺利地从16位实地址模式过渡到32位段式寻址的保护模式。又在arch/i386/boot/compressed/head.S的帮助下实现了内核的自解压,并且从arch/i386/kernel/head.S中的startup_32开始。现在在线性地址0x100000(1M)处开始就是我们的解压后的内核了。而startup_32()的地址恰好是0x100000。由于还没有开启页面映射,所以必须引用变量的线性地址(即变量的虚拟地址-PAGE_OFFSET),带来了很多不便。所以下一步的任务,就是建立页表,开启页面映射了。我们不妨从arch/i386/kernel/head.S入手。
由于在Linux中,每个进程拥有一个页表,那么,第一个页表也应该有一个对应的进程。通常情况下,Linux下通过fork()系统调用,复制原有进程,来产生新进程。然而第一个进程该如何产生呢?既然不能复制,那就只能像女娲造人一样,以全局变量的方式捏造一个出来。它就是init_thread_union。传说中的0号进程,名叫swapper。只要swapper进程运行起来,调用start_kernel(),剩下的事就好办了。不过,现在离运行swapper进程还差得很远。关键的一步,我们还没有为该进程设置页表。
为了保持可移植性,Linux采用了三级页表。不过x86处理器只使用两级页表。所以,我们需要一个页目录和很多个页表(最多达1024个页表),页目录和页表的大小均为4k。swapper的页目录的创建与该进程的创建思维类似,也是捏造一个页表,叫swapper_pg_dir.
417 ENTRY(swapper_pg_dir)418         .fill 1024,4,0
它的意思是从swapper_pg_dir开始,填充1024项,每项为4字节,值为0,正好是4K一个页面。
页目录有了,接下去看页表。一个问题产生了。该映射几个页表呢?尽管一个页目录最多能映射1024个页表,每个页表映射4M虚拟地址,所以总共可以映射4G虚拟地址空

间。但是,通常应用程序用不了这么多。最简单的想法是,够用就行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值