编译的内核可能会很大,故这里可以压缩一下。而在内核文件中需要解压,所以就会有一段自解压代码。
在uboot启动内核的时候,调用了函数: thekernel(0,MACH_ID,params_addr )
0 存放在r0寄存器
MACH_ID 存放在r1
params_addr存放在r2
1. 首先处理uboot传入的参数。
获取处理器id,查看内核是否支持这个处理器CPU。
获取uboot传入的机器ID,查看内核是否支持所运行该系统的单板。
建立一级页表,使能mmu。
跳转到start_kernel。内核的第一个C函数。
处理传入的启动参数。
启动参数包括: 内存大小等。
start_kernel
setup_arch
setup_command_line
parse_early_param
do_early_param
从__setup_start到__setup_end调用函数,使用方法如下:
for (p = __setup_start; p < __setup_end; p++) {
if (p->early && strcmp(param, p->str) == 0) {
if (p->setup_func(val) != 0)
printk(KERN_WARNING
"Malformed early option '%s'
", param);
}
unkown_bootption
reset_init
kernel_init
prepare_namespace
mount_root //挂载根文件系统
init_post
//执行运用程序
/* 打开“/dev/console”终端设备文件 */
/* 启动execute_command定义的函数 一旦执行,将做为第一个应用程序,不会退出 */
/* 如果没有以上函数,将执行 “/sbin/init” 函数 */
/* /etc/init */
/* /bin/init */
/* 如果没有以上的第一个应用,则系统无法启动 */
挂载根文件系统。
最终目的是运行应用程序
busybox
/* parse_inittab 打开解析配置文件 /etc/inittab */
/* inittab格式 */
/* <id>:<runlevel>:<action>:<process> */
/* id 转化为 /dev/id 用作终端
runlevels: 忽略
action : 执行时机askfist sysinit等
process : 应用程序或脚本
*/
new_init_action( action, command, cons )
创建一个action,并填写结构体
将这个结构体放入init_action_list链表
运行链表中的函数,创建为进程,并从链表中删除。
构造inittab
console ::askfirst:-/bin/sh
添加虚拟文件系统。
::sysinit:/etc/init.d/Rcs /*开机启动脚本*/
可将下面命令添加到rcs,开机可自己启动mount -t proc none /proc
也能用mount -a /*依赖 /etc/fstab文件 */
/etc/fstab文件格式
device mount-option type options dump fsck order
proc /proc proc defaults 0 0
执行之后就能使用ps命令。
udev为自动创建到/dev/设备节点的简化版本。
mdev为udev的简化版本。
在/etc/fstab中添加
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
在rcs中添加
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug //支持热插拔设备
mdev -s