linux内核启动流程
https://www.cnblogs.com/chenshikun/p/9389578.html
Linux内核的引导
https://www.cnblogs.com/wanghuaijun/p/7189769.html
Linux内核引导过程
https://blog.csdn.net/qingdaohaishanhu/article/details/88084492
探本溯源——深入领略Linux内核绝美风光之系统启动篇(一)
https://blog.csdn.net/jn1158359135/article/details/7330849
http://home.ustc.edu.cn/~hchunhui/linux_boot.html
CS是代码段寄存器,IP是指令指针寄存器(相当于偏移地址),存储的是代码指令的地址。CS:IP共同作用生成了代码地址,具体算法是CS左移4位+IP即是代码地址。例如CS=0xf000,IP=0xfff0,则代码地址为0xffff0.
.global/.globl 命令
.global symbol
.global 使得连接程序(ld)能够识别 symbl
声明symbol是全局可见的。标号_start是GNU链接器用来指定第一个要执行指令所必须的,同样的是全局可见的(并且只能出现在一个模块中)
例如:
.global _start #定义 _start 为外部程序可以访问的标签
.section 命令
是汇编语言汇中最为重要的命令之一,作用是定义内存段
该命令后只跟一个参数,即它声明的段的类型。
例如:
.section .text #定义文本段(代码段)
.section .data #定义数据段
.section .bss #定义 bss 段
汇编-自定义section
1.1、语法格式
.section section_name[,"flags"[,%type[,flag_specific_arguments]]]
1.2、作用
定义一个段,每一个段以段名为开始,以下一个段名或者文件结尾为结束。
ELF格式允许的段标志: a:可分配
w:可写段
x:执行段
例子:
.section ".customtext", "ax"
objdump -h a.out
Idx Name Size VMA LMA File off Algn
0 .customtext 00000024 0000000000400078 0000000000400078 00000078 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
标准支持的section, .data, .text, .bss
Idx Name Size VMA LMA File off Algn
0 .text 00000024 00000000004000b0 00000000004000b0 000000b0 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 0000001c 00000000006000d4 00000000006000d4 000000d4 2**0
CONTENTS, ALLOC, LOAD, DATA
首先cpu是需要访问内存地址(DRAM)的。cpu上电之后直接将地址寄存器设置为0xffff fff0,这个地址的指令在做最终被解析成
BIOS中的ROM中的一个地址,这个地址会进行一下操作:
1、对硬件执行一系列测试,用来检测现在有哪些设备以及这些设备是否正常运转,这个阶段被称为POST(Power-On-Self-Test,加电自检)。
2、初始化硬件设备,这个阶段保证所有的硬件设备操作不会引起IRQ(中断请求)线与I/O端口的冲突,最后显示系统中安装的所有PCI设备的一个列表。
3、搜索一个操作系统来启动。这个过程可以根据用户设置的顺序依次进行访问系统中的软盘、硬盘以及CD-ROM的第一个扇区(即引导扇区),通常是在开机时按del键进入BIOS的设置界面,但也可能是其他键,视各个具体的PC而定。
4、按上述访问次序找到一个有效设备后,即将第一个扇区的内容拷贝到RAM中物理地址0x0000 7c00处,随后跳转到该地址开始执
BIOS过程只能在实模式下运行,所以Linux一旦进入保护模式就不再使用BIOS,而是为计算机上的每个硬件设备提供各自的设备驱动程序
引导装入程序是由BIOS装载,用来把操作系统的内核映像装载到RAM中,该可执行程序存放在硬盘的第0个磁道第0个扇区上,由于总共只需占用较少(512字节)的存储空间,故也可称之为引导记录,除此之外该引导记录还包括64字节的分区表以及2个字节标识有效引导记录结尾的标签(0x55 0xAA).但从Linux2.6开始不再执行这样的引导装入程序,这一点可以通过从header.S文件剖析得知
我们也可以看到在完成POST以及一系列的初始化工作后,BIOS将bootloader加载至物理地址0000 7c00处,而令人困惑的是,内核的启动扇区bootsect的起始地址并未被严格限制,这其实是由于Linux内核允许使用多种bootloader所导致的,比如前文所提到的LILO以及GRUB,在现实情况中存在更多不同类型的bootloader,不同的bootloader可能将实模式的起始地址加载至不同的位置,然而在x86架构下的GRUB设置的起始地址正是0x9 0000