补充内容.

Signed-off-by: chen.yang <chen.yang@yuzhen-iot.com>
This commit is contained in:
chen.yang 2022-04-28 11:44:47 +08:00
parent 56fc0372e4
commit cd3b7008e9
1 changed files with 33 additions and 1 deletions

View File

@ -35,6 +35,22 @@ mkimage -n 'linux-2.6.32' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x3
GRUB 或 UBoot 最主要的工作是准备内核运行环境,包括设置启动引导参数等。如设置串口输出的波特率,使用的设备树文件,内核或驱动的参数等。
\<Linux Kernel Source>/Documentation/arm/Booting
1. Setup and initialise RAM
2. Detect the machine type
3. Setup the device tree
4. Load initramfs
5. Calling the kernel image
引导系统将内核装载到指定位置并跳转到入口点去执行。在[内核内存管理](./8.11_内核内存管理.md)提到,内核对低端内存进行了直接映射,而引导系统加载内核的地址范围,也正是在此段区域。
引导系统将 zImage 加载到对应地址上后,就会执行 zImage 中的自解压程序,将内核释放。
预留 0x800032k 的空间给内核参数。
TODO: 只要不冲突UBoot 可以将 zImage 加载到任何位置zImage 自己会将自己释放到正确位置上。
### UBoot 引导
TODO:
@ -64,7 +80,9 @@ uImage启动
```cpp
arch/arm/kernel/head.S // 内核的启动汇编
|
+----secondary_start_kernel // 跳转到 C 语言的入口函数
+---__create_page_tables // 创建内核运行时所需的 rodata、data、bss 段
|
+---secondary_start_kernel // 跳转到 C 语言的入口函数
|
----init/main.c —> void __init start_kernel(void) // C 语言的程序入口
|
@ -90,3 +108,17 @@ arch/arm/kernel/head.S // 内核的启动汇编
8. device_initcall()/moudle_init()/device_initcall_sync()
9. late_initcall()/late_initcall_sync()
2. 同一优先级的模块由 Makefile 决定,排在 Makefile 前面的模块先加载。
## initramfs
内核启动后就要挂载 rootfs但是 rootfs 在外部存储器中,因此需要加载外存的驱动程序,而外存的驱动很可能也在 rootfs 中,必须先加载 rootfs 才能加载驱动。此时就陷入先有鸡还是先有蛋的问题中。Linux 系统解决此问题的办法就是使用 initramfs。
initramfs 是一个内存文件系统,可以一些必要的驱动程序或工具打包进该文件系统。这个文件系统由 Bootloader 加载进内存,如 GRUB 或 UBoot内核直接使用即可。
initramfs 不是必须的,如果全部必须的驱动已经 build in 到内核,则可以不使用 initramfs。
## rootfs
TODO: 挂载外存驱动和 init 进程谁先谁后?
有了外存驱动以后,内核可以加载对应的外存驱动,执行第一个进程,即 init 程序,并挂载文件系统。但是都需要挂载哪些磁盘分区,哪个磁盘分区才是根文件系统呢?这是由 /etc/fstab 文件决定的。