arm linux 启动之三:kernle_init

        本文介绍arm linux启动的第三部分,就是1号进程kernel_init的执行,直到调用第一个用户进程init,即busybox根目录的linuxrc。

         1. init_pid_ns.child_reaper = current 把当前进程设为接受其他孤儿进程的进程

         2.  smp_init()及其它smp相关的初始化,体系相关的初始化。

         3. do_basic_setup()设备驱动的加载和初始化(直接编译进内核的模块)。

                 1)init_workqueues 初始化中断下半部的队列。

                 2)usermodehelper_init,初始化工作队列khelper

                 3)init_tmpfs,tmpfs文件系统注册和挂载

                 4)driver_init,建立设备驱动模型sysfs的kset、kobject和subsystem结构,并向其中注册cpu、内存和总线的驱动

                 5)do_initcalls 初始化linux启动的init段的所有函数。以模块的初始化为例

#define __define_initcall(level,fn,id) /  

 static initcall_t __initcall_##fn##id __used /  

 __attribute__((__section__(".initcall" level ".init"))) = fn

#define device_initcall(fn)  __define_initcall("6",fn,6) 

#define __initcall(fn) device_initcall(fn) 

#define module_init(x) __initcall(x);

                 可见模块的初始化是在第6个level,do_initcalls从第0个层次开始执行,在vmlinux.lds中确定。

#define INITCALLS       /  

 *(.initcallearly.init)      /  

 VMLINUX_SYMBOL(__early_initcall_end) = .;   /  

   *(.initcall0.init)      /  

   *(.initcall0s.init)      /  

   *(.initcall1.init)      /  

   *(.initcall1s.init)      /  

   *(.initcall2.init)      /  

   *(.initcall2s.init)      /

...

               各个子模块的执行顺序为:

#define pure_initcall(fn)  __define_initcall("0",fn,0)  

#define core_initcall(fn)  __define_initcall("1",fn,1)  

#define core_initcall_sync(fn)  __define_initcall("1s",fn,1s)  

#define postcore_initcall(fn)  __define_initcall("2",fn,2)  

#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)  

#define arch_initcall(fn)  __define_initcall("3",fn,3)  

#define arch_initcall_sync(fn)  __define_initcall("3s",fn,3s)  

#define subsys_initcall(fn)  __define_initcall("4",fn,4)  

#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)  

#define fs_initcall(fn)   __define_initcall("5",fn,5)  

#define fs_initcall_sync(fn)  __define_initcall("5s",fn,5s)  

#define rootfs_initcall(fn)  __define_initcall("rootfs",fn,rootfs)  

#define device_initcall(fn)  __define_initcall("6",fn,6)  

#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)  

#define late_initcall(fn)  __define_initcall("7",fn,7)  

#define late_initcall_sync(fn)  __define_initcall("7s",fn,7s)  

            

       6)检测ramdisk_execute_command中是否存在用户init进程,支持initrd(ramdisk)引导的嵌入式系统可能会将定制的init用户进程和内核一起打包。如果没有,就根据command_line的启动命令(uboot中的bootargs)---rootfs=yaffs 和mtd=/dev/mtdblock*来挂载根文件系统,该部分在init_post中进行。             

       7)init_post()

                i.unlock_kernel()

                ii.system_state = SYSTEM_RUNNING; 

                iii.run_init_process(execute_command);根据command_line的启动命令(uboot中的bootargs)---rootfs=yaffs 和mtd=/dev/mtdblock*来挂载根文件系统。并在根目录中寻找init=/linuxrc的用户进程来执行。如果没有/linuxrc。按以下顺序执行init。

               run_init_process("/sbin/init");
               run_init_process("/etc/init");              

              _init_process("/bin/init");
              run_init_process("/bin/sh");

              从此就进行用户进程啦。

 

 

你可能感兴趣的:(ARM,linux启动,init进程,1号进程,kerne_init)