Linux内核剖析——操作系统的启动
一.总体功能
1.从通电到BIOS跳转
1.1 CPU在通电后,先进入实模式,设置CS=0XFFFF,IP = 0X0000(指向BIOS)
1.2 BIOS进行执行系统监测,并且在地址=0处初始化中断向量
1.3 将启动设备的第一个扇区(引导扇区,512B)读入0x7c00处
1.4 设置CS=0X07C0,IP=0X0000,跳转到该地址
2.BootSect.S
2.1 跳转到0x7c00时,该部分存放的是BootSect.S的程序,操作系统的所有故事从这开始
2.2 开始执行后,把自身移动到地址0x90000处,并把setup.S读入到0x90200处,内核其他部分被读入到0x10000处
机器从接电到开始的执行顺序如图
3.setup.S
3.1 进入setup.后,将会自动识别主机的某些特性和VGA卡类型,并可以要求用户选择显示模式。
3.2 将系统从0x10000处移动到0x0000处,进入保护模式并跳转到系统模块
4.head.S
设置并加载IDT,GDT,分页,CPU,并调用main.C中的main程序
5.Main.c
执行main程序
6.系统启动程序转移图
7.部分说明
7.1 bootsect.s为什么不直接移动内核程序位置,而要在setup.s中移动?
ans:
setup.s中的部分代码需要用到BIOS提供的中断向量表获取系统信息,在使用完BIOS之后才可将该区域覆盖。
- 2 仅在内存中加载了上述内核功能并不能让Linux系统运行,仍需要有完整的基本文件系统支持,即称为根文件系统。Linux0.12 使用了Minix的文件系统
二.BootSect.S 代码解析
主要作用
该程序的主要作用是把自己移动到0x90000处并执行,把第二个扇区开始的四个扇区的Setup.s模块加载到bootsect.s之后,使用0x13中断取用当前引导盘的参数,并显示Loading system字符串。随后确定根文件系统的设备号,保存于root_dev,最后跳转到setup处去执行setup.s程序。后缀是大写的S,可以使用GNU C的预处理功能。
核心代码
BOOTSECT = 0X07C0
INITSEG = 0X9000
SETUPSEG = 0X9020
mov ax,#BOOTSECT
mov ds,ax
mov ax,#INITSEG
mov es,ax
mov cx,256
sub si,si
sub di,di
rep
movw //将DS:SI的内容赋值道ES:DI中,即把自身移动到0x90000处
jmpi go,INITSEG//因为程序空间已经移动,所以需要使用jmpi指令进行继续执行
go:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax//把段寄存器全部初始化为当前代码段
mov sp,0xff00//初始化栈
....//略过其余代码
load_setup://载入setup程序
xor dx,dx
mov cx,0x0002//扇区号为2
mov bx,0x0200
mov ax,0x0200+SETUPLEN//从第二个扇区开始,读4个扇区
int 0x13
//以上初始化0x13参数,并进行读取扇区,读入到es:bx
jnc ok_load_setup
xor dx,dx
xor cx,cx
int 0x13
j load_setup
ok_load_setup:
//..略去打印loading system部分
call read_it//读磁盘上的system模块
jmpi 0,setupseg//跳转到setup.s
//
三.Setup.S 代码解析
主要作用
利用BIOS中断读取机器系统数据,并将这些数据保存到0X90000的位置,覆盖掉BootSect.s的数据,这些参数将被内核中的相关程序使用
接着将system模块移动到0x0000处,加载idtr和gdtr,开启CPU保护模式,并跳转到最前面的head.S运行
为了能让head.S在保护模式中运行,本程序中临时设定了IDT和GDT,并在GDT中设置了当前内核代码段的描述符和数据段的描述符
核心代码
start:
mov ax,INITSEG
mov ds,ax//将DS设置为INITSEG
mov ah,0x03
xor bh,bh
int 0x10
mov [0],dx//通过中断取得光标位置
mov ah,0x88//获取扩展内存中断的功能调用
int 0x15
mov [2],ax//存储扩展内存数值
....//进行一系列参数获取
cli //不允许中断
mov ax,0x0000
cld
do_move:
mov es,ax//目的地址
add ax,0x1000
cmp ax,0x9000//是否已经移动玩
jz end_move//是,则跳转
mov ds,ax//源地址
sub di,di
sub si,si
mov cx,0x8000//移动64KB
rep
movsw
jmp do_move
call empty_8042//选通A20地址控制线,为了能使用1MB以上内存
mov al,0xd1
out 0x64,al
call empty_8042
mov al,0xdf
out 0x60,al
call empty_8042
mov ax,0x0001
mov cr0,ax//开启保护模式
jmpi 0,8//保护模式寻址,查询GDT进入0地址处
四.head.S 代码解析
notice:
head.s使用AT&T汇编编写,语法略有不同
主要作用
加载各个数据段寄存器,重新设置中断描述符表idt,重新设置GDT,检测A20地址线是否打开,设置分页后,打开main
核心代码
//主要就是调用main函数,过于简单,不写了
Linux内核剖析——操作系统的启动的更多相关文章
- 【转帖】Linux的历史----Linux内核剖析(一)
Linux的历史----Linux内核剖析(一) 2015年04月09日 10:51:09 JeanCheng 阅读数:11351更多 所属专栏: Linux内核剖析 版权声明:本文为博主原创文 ...
- [转帖]Linux内核剖析(一)Linux的历史
Linux内核剖析(一)Linux的历史 https://www.cnblogs.com/alantu2018/p/8991158.html Unix操作系统 Unix的由来 汤普逊和里奇最早是在贝尔 ...
- Linux内核剖析(四)为arm内核构建源码树
前面说到要做linux底层开发或者编写Linux的驱动,必须建立内核源码树,之前我们提到过在本机上构建源码树—-Linux内核剖析(三),其建立的源码树是针对i686平台的,但是我么嵌入式系统用的是a ...
- 通过gdb跟踪Linux内核装载和启动可执行程序过程
作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验目的:通过对一个简单的可执 ...
- linux内核剖析(零)linux系统启动过程详解-开机加电后发生了什么
本文参考了如下文章 深入理解linux启动过程 mbr (主引导记录(Master Boot Record)) 电脑从开机加电到操作系统main函数之前执行的过程 详解linux系统的启动过程及系统初 ...
- linux系统启动过程具体解释-开机加电后发生了什么 --linux内核剖析(零)
本文參考了例如以下文章 深入理解linux启动过程 mbr (主引导记录(Master Boot Record)) 电脑从开机加电到操作系统main函数之前执行的过程 详细解释linux系统的启动过程 ...
- Linux内核装载和启动一个可执行程序
“平安的祝福 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 理解编 ...
- linux内核剖析(六)Linux系统调用详解(实现机制分析)
本文介绍了系统调用的一些实现细节.首先分析了系统调用的意义,它们与库函数和应用程序接口(API)有怎样的关系.然后,我们考察了Linux内核如何实现系统调用,以及执行系统调用的连锁反应:陷入内核,传递 ...
- Linux内核剖析(五)Linux内核的构建过程
参考 一次实验引发的故事 – kernel build system探索—vmlinux是如何炼成的– kernel makefile 深度探索Linux操作系统:系统构建和原理解析.pdf 问题 在 ...
随机推荐
- Redis Hashes 数据类型简述
Redis Hashes 是我们日常使用中比较高频的 Redis 数据类型,内部使用 Redis 字典结构存储,底层基于哈希表结构实现. 下面从哈希表节点,哈下表结构,Redis 字典,Redis 字 ...
- 第六章 Linux系统之文件管理
一.文件管理概述 1.对文件做些什么? 谈到Linux文件管理,首先我们需要了解的就是,我们要对文件做些什么事情? 其实无非就是对一个文件进行创建.复制.移动.查看.编辑.压缩.查找.删除等等 2.内 ...
- apktool重新打包添加签名
一.生成apk apktool b 反编译后项目目录 -o 新apk名称.apk 二.生成签名 keytool -genkeypair -alias 新apk名称.apk -keyalg RSA -v ...
- 【0】TensorFlow光速入门-序
本文地址:https://www.cnblogs.com/tujia/p/13863181.html 序言: 对于我这么一个技术渣渣来说,想学习TensorFlow机器学习,实在是太难了: 百度&qu ...
- MongoDB 数据备份和恢复 --- MongoDB基础用法(七)
数据备份 在Mongodb中我们使用mongodump命令来备份MongoDB数据.该命令可以导出所有数据到指定目录中. mongodump命令可以通过参数指定导出的数据量级转存的服务器. mongo ...
- 2020 10月CUMTCTF wp
华为杯 × 签到杯√ 论比赛过程来说没什么很大收获 但看师傅们的wp感触很多 赛后复现慢慢学吧 Web babyflask flask ssti模板注入: payload{{key}}发现[]以及类似 ...
- CodeForces 题目乱做
是个补题记录. 1419 除了 F 场上都过了. CF1419A Digit Game 这题好多人 FST 啊-- 考虑如果串长为奇数那么最后操作的肯定是第一个人,串长为偶数的最后操作的肯定是第二个, ...
- STM32入门系列-STM32时钟系统,时钟初始化配置函数
在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...
- drf 权限校验设置与源码分析
权限校验 权限校验和认证校验必须同时使用,并且权限校验是排在认证校验之后的,这在源码中可以查找到其执行顺序. 权限校验也很重要,认证校验可以确保一个用户登录之后才能对接口做操作,而权限校验可以依据这个 ...
- Kubernetes Pod驱逐策略
Kubelet 能够主动监测和防止计算资源的全面短缺. 在资源短缺的情况下,kubelet 可以主动地结束一个或多个 Pod 以回收短缺的资源. 当 kubelet 结束一个 Pod 时,它将终止 P ...

