内核态下干了什么——构建内核。
在init进程中,一个进程有两种状态。1为内核态,init属于内核进程。2.用户态,自己将init转为用户态。从进程1之后的进程就都可以工作在用户态。
内核态中重点干了一件事情,挂载rootfs,找用户态init程序,并就将自己转变为用户态,因为用户态程序在rootfs中。内核智能执行哈函数,不存在广义上的应用。应用程序不会属于用户态,不在内核源代码中。
init大部分有意义的事情是在用户态进行的,是别的或操作系统的开端,别的程序都将源于init进程,都派生于此。可以说用户态下的进程都是派生进程。
init进程在内核态下,通过kernel_execve执行一个用户空间编译连接的应用完成跳跃。跳跃后还是用户态的进程1,这个跳跃过程不可逆,是说明操作系统已经运行起来了,未来调用内核态只能通过API进程访问。
init进程构成看用户交互界面——人机交互。init进程是所有进程(1号进程)的父进程。
init进程派生了login进程用于用户登录与命令执行,也派生了shell进程执行命令行环境的解析与执行。shell进程可以启动别的用户进程,用户可以在命令行下./xxx执行进程或程序。
linux系统中每个进程都有一个自己的文件描述符表,记录了本进程打开的文件。linux系统中,一切都抽象为了文件,访问设备都会去打开这个设备文件。
描述符eg:
/dev/fb0 LCD设备(真实设备)
/dev/buzer 蜂鸣器(真实设备)
/dev/console 控制台(虚拟设备)
打开文件描述符sys_open();打开console文件用sys_open(0);复制两次文件描述符得到单个文件描述符0/1/2,构成标准输入/标准输出/标准err。
使用prepare_namespace挂载rootfs。mount_block_root(root_device_name, root_mountflags);
uboot通过传参通知内核rootfs的位置/类型 bootargs。root=/dev/mmcblock0p2 rw 位置
rootfstype=ext3 类型。
内核rootfs挂载成功将打印VFS:mounted root。失败则打印No Filee system could mount root,tried。然后重启。
mmc:SD/inand blk0 inand p 2 inand的2分区。blk1 sd 分区 2分区 rw可写。
init_post() 寻找用户态下的进程1
run_init_process()
kernel_execve() 执行用户态下的进程1
确定init程序是谁:先从uboot看cmdline指定执行程序。init=/linuxrc 指定的根文件系统中的进程1.
如果uboot没有指定root或不存在相关的根文件系统,则会执行备用方案:
/sbin/init
/etc/init
/bin/init
/bin/sh
如果这四个方案都寄了,则内核err。