Linux系统初始化流程

linux系统的启动,指的是从系统加电到系统控制台显示“login:”登录提示符为止的系统运行阶段,与这部分动作密切相关的代码主要是:

  • 四个汇编程序:bootsect.S setup.S head.S entry.S
  • init目录下的main.c文件

    主要查看init/main.c中的start_kernel函数:
    这里写图片描述

在系统启动过程中,主要关注一下几个方面:

  1. 中断系统及调度系统
  2. 文件系统的初始化
  3. 设备管理系统的初始化
  4. 网络协议的初始化

init/main.creset_init函数:
这里写图片描述

在此函数中,有kernel_thread函数,这个函数创建了内核线程,原型如下:

int kernel_thread(int (*fn), void *arg, unsigned long flags)

此函数定义在arch/xxx/kernel/process.c中,它利用do_fork()函数创建一个新的内核态线程,linux的内核线程是没有虚拟存储空间的进程,它们运行在内核中,直接使用物理地址空间。
kernel_thread创建的新的内核线程是init,然后返回,执行unlock_kernel(与start_kernel中的lock_kernel对应),接着执行cpu_idle(),这实际是执行初始化主线程的归宿:它观察自己是否处于TIF_NEED_RESCHED——在need_resched实现,如果不是,就让自己睡眠,否者完成schedule()函数。TIF即Thread Information Flag的意思。

下一步转入init函数中:
这里写图片描述

init线程调用了许多函数,但与网络有关的在do_basic_setup中初始化的sock_init(),然后继续执行do_initcalls函数,此函数定义在c文件中,有两个重要的变量__initcall_start__initcall_end,它们的定义如下:

extern initcall_t __initcall_start, __initcall_end;
static void __init do_initcalls(void)
{
    initcall_t *call;
    int count = preempt_count();
    /*从start遍历到end*/
    for(call = &__initcall_start; call < &__initcall_end; call++){
        char *mesg;
        ......
        (*call)();

        msg = NULL;
}

}

initcall_t类与__initcall_start__initcall_end定义在include/linux目录下的init.h文件中。

你可能感兴趣的:(kernel)