1. 内核镜像文件
1.1. vmlinux
vmlinux是elf(Excutable And Linkable),即可执行文件。里面含有调试信息,可用于调试,所以占有空间较大。gcc编译连接之后直接生成vmlinux文件。
1.2. Image
efl文件含有调试信息,太占空间了,gcc提供了objcopy工具,可以将elf文件中的调试信息去除,只留下可执行指令的二进制指令。
1.3. zImage
Image文件依然比较大,此时可以使用gzip来压缩Image文件得到zImage文件。引导文件在加载zImage文件之后,会利用gzip进行解压,然后执行相关指令。
1.4. bzImage
gzip的压缩率不太优秀,bzImage是一种采用更高压缩比的算法处理Image文件之后得到的文件。
在编译内核时,直接使用make bzImage即可以编译连接生成vmlinux文件,然后objcopy转换为Image文件,再压缩为zbImage文件。一般情况下均使用bzImage文件。ubuntu中会用vmlinuz来作为bzImage文件的后缀。
1.5. uImage
uImage文件是专为uboot准备的镜像文件格式,它会在zImage文件前面加上一个64byte的信息头,用来标识镜像文件的类型,生成时间,加载启动地址,文件有效长度等信息。一般使用make uImage生成。
1.6. ko
Linux内核可以编译为一个elf文件,直接被引导程序加载支行。但是如果只是想修改内核其中的一个功能,就必须编译整个内核代码,非常耗时。为此,Linux整个内核也是一个主elf文件,加上其他这么多动态库文件。内核的动态库文件即ko文件。一般存放在lib\modules中对应的内核目录中。
1.7. initrd
内核启动前的初始化执行文件,在内核真正启动前加载好一些常用的驱动代码。
1.8. System.map
内核的符号文件,供一些内核附带的工具使用。相当于内核的一个接口导出文件,对应函数符号与函数地址,供外部工具调用。
2. Linux的启动过程
2.1. Bios
Bios会根据设置的Boot优先顺序去读取指定的存储设备。存储设备的开始存放着MBR,MBR上记录着一段启动代码,会去存储设备指定位置读取内容。早期的设备是bios+MBR,此方式比较受限,不够灵活。新的电脑葳都采用UEFI+GPT,支持更大的容量,更多的逻辑分区数。
2.2. grub
MBR/GPT上存储着grub代码,用以引导具体启动哪个操作系统。是一种常见的Bootloader程序。grub会将initrd或vmlinz文件加载到ram指定位置上。
2.3. initrd
在加载操作系统内核代码之前,grub会先加载initrd文件,即Initiative RAM dis。initrd主要完成磁盘和网卡等的驱动挂载,这样才内核直接启动之后,才能去访问硬盘或网络来完成进一步的启动。如果要增加自定义驱动,需要修改此文件。
2.3. systemd
systemd,system daemon,系统守护进程,Linux系统的第1个进程,PID为1。systemd可以管理系统所有资源。早期的1号进程是sysvinit,其启动完整内核的过程是顺序的,这样启动会比较慢。而systemd则是尽量并行启动其他进程,这样系统启动会更快。传统的sysvinit会启动很多比较少用到的进程,而systemd则是动态启动其他进程,当需要的时候才启动其他进程。另外systemd还动态挂载挂载点,访问到的时候才挂载。systemd在启动完所有守护进程之后,开始启动6个控制台终端,其中有命令行终端和图形窗口终端。可以用Alt+Fn进行切换。
Service unit:系统服务
Target unit:多个Unit构成的一个组
Device Unit:硬件设备
Mount Unit:文件系统的挂载点
Automount Unit:自动挂载点
Path Unit:文件或路径
Scope Unit:不是由Systemd启动的外部进程
Slice Unit:进程组
Snapshot Unit:Systemd快照,可以切回某个快照
Socket Unit:进程间通信的socket
Swap Unit:swap文件
Timer Unit:定时器