linux启动过程中建立临时页表
intel的x86这种架构为了兼容以前同系列的架构有一些很繁琐无用的东西。比如分段和分页两种机制都可以实现隔离进程的内存空间,在x86上两种机制都有,用起来比较繁琐。所以linux内核在启动的时候通过把各个段的起始地址都设置成0,把逻辑地址直接映射到虚拟地址,也就是说在linux里逻辑地址和虚拟地址是相等的。所以看linux内存管理的时候集中精力于分页这种方式就可以了。
linux启动分两个阶段:
- 第一个阶段(汇编)建立分段机制(忽略),建立一个临时页表进入分页机制。
- 第二个阶段(C语言)初始化系统的各种资源(硬件/软件)。
这篇只讨论建立临时页表的过程。
linux内核被加载进内存以后,在内存空间的分布如下图:
这个映射图可以参考arch/i386/kernel/vmlinux.lds.S里的代码
不管在临时分页机制里还是之后真正的分页机制里linux要调用自己的函数是需要把自身映射进页表里的。在进入真正的分页机制之前linux需要一个临时的内存管理系统来管理低端内存,所以这个临时的内存管理系统也需要映射进页表。需要映射进页表的内存包括:
- linux内核。
- 临时页表(这个不一定需要映射进页表,但是为了方便也这么做了)。
- 128k的临时内存管理系统(其实就是用的位图管理1G的低端内存,2^32/4096/8 = 128K)。
好了,可以看代码了
page_pde_offset = (__PAGE_OFFSET >> 20);
movl $(pg0 - __PAGE_OFFSET), %edi
movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
movl $0x007, %eax /* 0x007 = PRESENT+RW+USER 这是页表属性*/
10:
leal 0x007(%edi),%ecx /* Create PDE entry */
movl %ecx,(%edx) /* Store identity PDE entry */
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
addl $4,%edx
movl $1024, %ecx /*1024个页表*/
11:
stosl
addl $0x1000,%eax
loop 11b
/* End condition: we must map up to and including INIT_MAP_BEYOND_END */
/* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
cmpl %ebp,%eax
jb 10b
movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
swapper_pg_dir就是页目录,在内核的.bss段,临时页表从pg0开始,查询arch/i386/kernel/vmlinux.lds.S可见pg0就在_end之后,128k就在临时页表之后。具体映射了多大的空间是不确定的,但是大概是8M,因为开始留了1M空间,内核大概占4M再加上页表本身和128K,两个页目录能映射8M内存正好包含这几项内容,所以一般书上会说映射了8M内存。
还有一个比较重要的是给init_pg_tables_end的赋值为最后一个页表的地址,所以紧跟init_pg_tables_end之后的是那128k的临时内存管理系统,再之后的内存都是空闲可用内存。
linux启动过程中建立临时页表的更多相关文章
- 嵌入式Linux启动过程中的问题积累
嵌入式Linux启动过程中的问题积累 Dongas 07-12-19 1.Bad Magic Number ## Booting image at 33000000 ... Bad Magic Num ...
- 如何设置linux启动过程中的停止阶段
设置方法: 1 启动过程中点击“e”键(fedora)或者"tab"(centOS)键进入目标启动项的命令行参数下,移除initrd所在行末尾的"quiet" ...
- Linux启动过程中几个重要配置文件的执行过程
Linux 登录后,配置执行顺序为(Debian Serials Capable):/etc/environment -> /etc/profile -> (~/.bash_profile ...
- Linux系统在启动过程中mbr主引导程序被破坏的解决方案
首先,mbr主引导程序被破坏是指系统在启动过程中,磁头找不到/boot分区(windows的启动分区在c盘). 1)下面我们模拟主引导分区被破坏的情况:(在启动分区划分446M的存储大小) 2)重启( ...
- Linux 启动过程详解
目录 1. Linux启动过程 2. 启动过程概述 3. 引导加载阶段 4. 内核阶段 4.1 内核加载阶段 4.2 内核启动阶段 5. 早期的用户空间 6. 初始化过程 6.1 SysV init ...
- 深入理解Linux启动过程
深入理解Linux启动过程 本文详细分析了Linux桌面操作系统的启动过程,涉及到BIOS系统.LILO 和GRUB引导装载程序,以及bootsect.setup.vmlinux等映像文件 ...
- Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)
启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...
- Linux启动过程详解
Linux启动过程详解 附上两张图,加深记忆 图1: 图2: 第一张图比较简洁明了,下面对第一张图的步骤进行详解: 加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...
- 从Linux启动过程到android启动过程
Linux启动过程: 1.首先开机给系统供电,此时硬件电路会产生一个确定的复位时序,保证cpu是最后一个被复位的器件.为什么cpu要最后被复位呢?因为 如果cpu第一个被复位,则当cpu复位后开始运行 ...
随机推荐
- ubuntu安装docker-ce 、docker-ce-cli、containerd.io
问题 ubuntu安装docker的时候特别慢,百度搜了一大堆都没讲到点子上,最后请教了大佬才知道是源的问题 安装 修改源 sudo gedit /etc/apt/sources.list 添加源 阿 ...
- Linux远程ssh执行命令expect使用及几种方法
expect命令实现脚本免交互 一.Linux下SSH无密码认证远程执行命令 在客户端使用ssh-keygen生成密钥对,然后把公钥复制到服务端(authorized_keys). 实现步骤: 1.客 ...
- CSS居中的多种方法
1.水平居中:text-align 与 inline-block 的配合 <div id = "div_center_align"> <div id = &quo ...
- python之cookie与session
cookie概念 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. cookie的工作原理是:由服务器 ...
- 一条 SQL 引发的事故,同事直接被开除!!
前言 Insert into select请慎用. 这天xxx接到一个需求,需要将表A的数据迁移到表B中去做一个备份.本想通过程序先查询查出来然后批量插入.但xxx觉得这样有点慢,需要耗费大量的网络I ...
- 常见重构技巧 - 5种方式去除多余的if else
常见重构技巧 - 去除多余的if else 最为常见的是代码中使用很多的if/else,或者switch/case:如何重构呢?方法特别多,本文带你学习其中的技巧. 常见重构技巧 - 去除多余的if ...
- 测试软件—禅道BUG管理工具
入禅 目录 入禅 1.禅道的基本使用 1.禅道的基本使用 admin(管理员) 部门:创建部门(需求部门,开发部门,测试部门,项目部门,产品部门) 组织:创建用户(产品经理,项目经理,开发人员,测试人 ...
- python语句与函数
赋值语句 : 分支语句 : 函数 :根据输入参数产生不同输出功能 程序的输入与输出 input() 从控制台获得用户输入的函数 使用格式 print()函数 以字符形式向控制台输出结果的函数 字符类型 ...
- 《Java从入门到失业》第四章:类和对象(4.4):方法参数及传递
4.4方法参数及传递 关于这个知识点,我想了很久该不该在这里阐述.因为这个知识点稍微有点晦涩,并且就算不了解也不影响用Java编写代码.不过笔者刚开始工作的时候,就是因为这块内容没有过多的关注,以至于 ...
- RabbitMQ安装、集群搭建、概念解析
RabbitMQ安装.集群搭建.概念解析 基本概念 为什么会产生MQ 1.解耦:采用异步方式实现业务需求达到解耦的目的. 2.缓冲流量,削峰填谷: 问:为什么会有流量冲击? 答:采用"直接调 ...