首页 > 其他分享 >boot sharing

boot sharing

时间:2024-08-09 16:18:46浏览次数:11  
标签:初始化 sharing init boot 文件系统 initrd 内核 内存

1.BootRom
计算机系统启动过程的第一步,负责进行硬件初始化和加载Boot Loader到RAM等基本操作
根据不同的启动模式(硬件拨码)去不同的存储设备取bootlaoder(决定指令从哪来
bootrom:
rom:掉电不易失存储器,通常为nor flash,可以芯片内执行
boot:存储在上述介质中的一小段引导程序,负责基本的硬件初始化、初始化片内一小片ram、加载bootloader等

1.1 BIOS和UEFI/EFI
1.1.1 BIOS
BIOS 是机器加电后运行的第一个程序,保存在只读存储器(ROM)中。启动信息保存在 CMOS 芯片中(RAM)
MS-DOS 分区:主引导记录MBR,分区表,MBR标记
1.1.2 UEFI/EFI
UEFI:统一可扩展固件接口
UEFI引导模式包含一个特殊分区EFI,用于存储.efi文件并且用于引导过程和引导加载程序【将引导程序存储在.efi文件中,而不是固件中】
采用GPT分区
省去了BIOS的自检过程
引导过程:boot.img(mbr 446B) ==> diskboot.img ==> kernel.img

1.2.启动流程
处理器上电,根据程序计数器pc去取第一条指令,译码,执行
initializes basic hardware, loads device tree and Linux

2.BootLoader-ABL XBL
Bootloader负责查找和加载应该在芯片上运行的最终操作系统或固件。与bootrom的一个主要区别是它通常在可写闪存中,可以更换或升级。、
主要任务:【设置内存管理、安全选项】正确的调用内核来加载操作系统/加载内核镜像和initframfs到内存,并将控制权交给内核
包括:初始化硬件设备、建立正确的内存空间映射、初始化栈、检测并初始化内存、初始化全局变量、加载程序,将特点软件组拷贝到RAM中,并运行
Bootloader 包含两个重要文件:init.s 和 main.c

Init.s 负责初始化堆栈和 BSS 段。它最终调用 main.c,后者负责初始化键盘、系统时钟、控制台等硬件。

最重要的是,引导加载程序在将执行移动到内核和 dis 之前会验证启动和恢复分区的完整性。

2.1 DTS
Device Tree可以描述的信息包括CPU的数量和类别、内存基地址和大小、总线和桥、外设连接、中断控制器和中断使用情况、GPIO控制器和GPIO使用情况、Clock控制器和Clock使用情况。
它通过bootloader将硬件资源传给内核,内核和硬件资源描述相对独立
设备树包含DTC(device tree compiler),DTS(device tree source)和DTB(device tree blob)
DTS:ASCII文本对设备树的描述
DTC:编译工具,把.dts文件编译成.dtb文件
Bootloader需要将设备树在内存中的地址传给内核。在ARM中通过bootm或bootz命令来进行传递。bootm [kernel_addr] [initrd_address] [dtb_address],其中kernel_addr为内核镜像的地址,initrd为initrd的地址,dtb_address为dtb所在的地址。若initrd_address为空,则用“-”来代替
boot工具启动内核的时候,会把这个文件加载到内存中,并且把内存地址告诉内核,内核就可以读到dtb文件了

2.1 文件系统
ramfs:文件系统,利用告诉缓存机制,使用系统物理内存,做成大小可以动态变化的基于内存的文件系统
工作于虚拟文件系统层,不能被格式化,可以创建多个
tmpfs:ramfs衍生,既可以使用物理内存也能用交换分区
rootfs:ramfs的一个空实例,内核启动初始化的根文件系统,一般是在start_kernel()函数中实现它的初始化
ramdisk:虚拟磁盘驱动器,它将一部分系统内存分配给一个虚拟磁盘驱动器,从而创建一个类似硬盘的存储设备(ramdisk是在一块内存区 域中创建的块设备,用于存放文件系统)
还可以存临时文件、缓存文件等需要快速访问的数据,因为内存的访问速度比硬盘快很多
常用:加速应用程序启动时间;提高系统性能;减少硬盘访问速度
Linux下实现:创建目录作为Ramdisk的挂载点;
驱动中预留:驱动初始化时申请物理页面用于制作ramdisk;将物理页面映射到内核虚拟地址空间;初始化设备队列并为Ramdisk创建块设备;将块设备和回调函数连接,并使用内存复制操作在内存的Ramdisk间读写数据
缺:ramdisk在使用的时候,这个假的块设备和高速缓存(页缓存和目录缓存)之间有数据的拷贝,而且它还需要文件系统的驱动来格式化和解释这些数据。所以,使用ramdisk不仅浪费了内存,还加重了cpu的负担,同时也无污染了cache,而且其所有的文件和目录都要通过页和目录缓存进行访问

2.2 initrd
两种格式:image格式和cpio格式【image-initrd和cpio-initrd】
initrd:和内核是编译成两个文件
image-initrd:

特点:image-initrd 文件需要先用 zip 方式解压得到 initrd 文件,然后在 Linux 下进行挂载并直接访问。
处理流程:
Boot loader(如 GRUB)将 initrd.img 初始化成一个设备 /dev/initrd,并将内核和 /dev/initrd 的内容加载到内存中。
内核将 /dev/initrd 设备的内容解压缩并拷贝到 /dev/ram0 设备上。
内核以可读写的方式将 /dev/ram0 设备挂载为原始的根文件系统。
执行 initrd 上的 /linuxrc 文件,加载内核访问根文件系统所需的驱动。
挂载真正的根文件系统,并继续正常启动过程1。
cpio-initrd:

特点:cpio-initrd 文件是一个 gz 压缩文件,可以使用 cpio 命令解压。
处理流程:
Bootloader 将内核和 initrd 文件加载到内存的特定位置,并把地址和大小传给内核。
内核判断 initrd 的文件格式,如果是 cpio 格式,将其内容释放到 /rootfs 中。
执行 initrd 中的 /init 文件,完成内核初始化工作
initramfs:和内核编译到了一个image文件,放在了.init.ramfs段内(实质上是一个cpio的数据文件,被链接到内核的.init.ramfs段,内核启动时会对数据进行解压,然后使用它作为临时的跟文件系统)

2.3 Uboot
引导启动内核
单进程
2.3.1 流程
硬件相关初始化:cpu管理模式、时钟、SDRAM、外部总线、代码搬运重定向、设置栈,.bss段
从flash中读出内核,启动内核:读取内核头部,移动内核到合适的加载地址,启动内核。c函数start_armboot():外设初始化、mainloop

3.kernel
主要任务:set up the cache, load drivers, mount the file system, start Kernel daemons, etc
内核映像被加载到内存并获得控制权之后,内核启动流程开始。
内核自解压

创建0号进程
设置CPU、内存、命令行参数、中断初始化、内存初始化、调度器初始化、控制组初始化、初始化/proc文件系统的根目录等
/proc文件系统:虚拟文件系统,内存中动态生成的文件系统。它允许用户和应用程序通过文件的读写来与内核通信
最后的arch_call_rest_init()函数里区分内核态和用户态、初始化1号进程(init)和初始化2号进程(kthreadd)

3.1 0号进程
init_task是Linux内核中的第一个线程,它贯穿于整个Linux系统的初始化过程中,该进程也是Linux系统中唯一一个没有用kernel_thread()函数创建的内核态进程(内核线程),它是内核静态创建的
如图是0号进程的定义:structur task_struck_init_task【init_task.c】

创建1、2进程后退为cpu_idle进程:当内核上没有任务可运行时就会运行idle进程,进入低功耗模式【cpu_startup_entry**调用cpu_idle_loop()】

3.2Init
由内核启动的第一个进程,PID=1
Init进程开始是在内核空间,完成挂载根文件系统之类的操作后,开始执行init程序后进入用户空间【通过运行一个用户态的应用程序进入用户态】static int __ref kernel_init(void *unused)
释放初始化内存、退出引导配置、页表隔离、设置NUMA非一致性缓存默认策略、执行一系列初始化
挂载根文件系统:ernel_init_freeable();里prepare_namespace()
run_init_process里调用kernel_execve执行初始化脚本

主要作用:
挂载 根文件系统。执行 init.rc 脚本
starts the daemons, such as bluetooth daemon, adb daemon, etc. d
handle low-level hardware interfaces including radio interface.
start vold, start the Zygote process

3.3 kthreadd
内核线程,创建后续的所有内核线程,是内核用于管理调度其他的内核线程的守护线程
int kthreadd(void *unused):初始化cgroup,创建想要内核线程,调度
static void create_kthread创建新线程
新线程执行kthread

3.4 udev
udev是linux kernel的设备管理器,在最新的内核版本中kernel_3.10中udev已经代替了devfs、hotplug等功能。它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。使用udev后,在/dev目录下就只包含系统中真正存在的设备。

Systemasroot
根文件系统已不再包含在 ramdisk.img 中,而是合并到了 system.img
Android 9 system-as-root 配置中,BOARD_BUILD_SYSTEM_ROOT_IMAGE 设为 true,这会强制编译将根文件系统合并到 system.img 中,然后将 system.img 作为根文件系统 (rootfs) 进行装载。此配置对于搭载 Android 9 的设备是强制性的,但对于升级到 Android 9 及搭载较低 Android 版本的设备是可选的。在 Android 10 system-as-root 配置中,编译始终将 $TARGET_SYSTEM_OUT 和 $TARGET_ROOT_OUT 合并到 system.img 中;此配置是搭载 Android 10 的所有设备的默认行为。

4 Init-Systemd
作为init软件,systemd程序的任务有如下工作
(1) 初始化文件系统,设置环境变量
(2) 挂载硬盘,/proc, /tmp, swap等等
(3) 根据设置的运行级别, 启动相应的守护进程
(4) 并在系统运行期间,监听整个文件系统获取源码:source后devtool modify systemd
cd workspace/sources/systemd/src/core main.c

PPT:

















一般目录位置:
/usr/lib/systemd/system/ :软件安装时添加的配置位置
/run/systemd/system/ :unit/service运行时生成的配置文件所在的目录
/etc/systemd/system/:系统或用户自定义的配置文件;初始化过程中systemd只执行该目录下的配置文件
/etc/systemd/system/default.target:systemd执行的第一个单元文件,符号链接到默认启动target对应的.target单元文件

标签:初始化,sharing,init,boot,文件系统,initrd,内核,内存
From: https://www.cnblogs.com/WScarlett/p/18345058

相关文章