基于 Linux 0.11 讲解 Linux 操作系统的启动原理

大家好,我是飞哥!

不知道大家有没有产生过一个疑问:从给 Linux 服务器按下开机电源按钮后到启动成功的一段时间里,在这中间 Linux 操作系统都做了哪些事情

在 Linux 服务器没有通电的时候,操作系统还只是躺在硬盘启动区中的一段程序,CPU 没有工作,内存也没有启动。但是在你按下开机键后,Linux 服务器内部就开始变得热闹了起来。一个电子世界被你激活了。经过几十秒或者几分钟的等待,Linux 服务器就可以使用了。

但这中间操作系统都干了啥呢?我有一位朋友叫闪客,就是因为对这个问题的好奇,花了两年时间写了 50 多篇文章,并还总结成了一本书。叫做《Linux 源码趣读》。这周,这本新书正式印刷出炉了。

对于 Linux 启动过程,代码的运行在书中总结成下面一张图来表示。但分了 50 小节来讲述每一个步骤中的细节。全书共 400 多页,250 多张精美的图解,五大部分,从头到尾把 Linux 0.11 全部核心代码讲述的一清二楚

基于 Linux 0.11 讲解 Linux 操作系统的启动原理_第1张图片

当你按下电源后,在主板上提前写死的固件程序 BIOS 会将硬盘启动区中的 512 字节 的数据原封不动地复制到内存中的 0x7c00 这个位置。

然后 CPU 开始跳转到这个位置开始启动引导执行。接着 CPU 的数据段寄存器 ds 、代码段集寄存器 cs 和 栈段寄存器 ss、栈基址寄存器 sp 都会进行初始化。接着除了引导区的 512 字节外的 200 多个扇区的内核代码都会被加载到内存中。

再接着内核会设置全局描述符表 GDT 也会被初始化。全局描述符表入口位置保存在 gdtr 寄存器中,是为了后面逻辑地址转化成物理地址时使用的。接着进入保护模式、开启分页机制后会进入到内核的 main 函数中。

是的,内核也有一个 main 函数。这个 main 函数非常重要,把操作系统的整个骨架都勾勒出来了。

void main(void) {
    ......
    mem_init(main_memory_start,memory_end);
    trap_init();
    blk_dev_init();
    sched_init();
    buffer_init(buffer_memory_end);
    hd_init();

    move_to_user_mode();
    if (!fork()) {
        init();
    }
    for(;;) pause();
}

可见 main 函数中包含了很多 init 函数。其中每一个 init 函数都对应着操作系统某个模块的初始化过程。具体包括内存模块初始化 mem_init、中断初始化 trap_init、块设备初始化 blk_dev_init、进程调度初始化 sched_init、硬盘初始化 hd_init 等。

  • 内存初始化是在内存中准备了一个数组。这个数组中的每一个元素是用来表示该页面是被使用了还是空闲。将所有的物理页都管理了起来。

  • 进程调度初始化中初始化了一个 task_struct 数组。每一个元素将来都会表示一个进程。并设置了时钟中断,将来用作触发调度。

  • 硬盘初始化后,内核打开允许硬盘控制器发送中断请求信号。

  • ......

上面描述的这些都是操作系统的第 0 号内核线程处理的。在操作系统中,0号内核线程是所有进程祖先,是操作系统Linux在初始化阶段从无到有的第一个内核线程

接着最后会切换到用户态模式。并通过 fork 系统调用创建一个 1 号内核线程。并在这个新的进程中继续进行初始化。这个新内核线程中 中会将眼影盘的基本信息(磁头数、柱面数、扇区数)存到一个内核数组中。还会加载根文件系统。顺着 inode 可以找到所有文件。通过 open 系统调用打开了 /dev/tty0,为进程设置好了 0 号、1 号、2号文件描述符。这就是 Linux 的标准 IO:stdin、stdout、stderr。

后面创建的所有进程也好线程也罢,都会继承进程 1 的 0 号、1 号、2号文件描述符。可以使用这 3 个标准 IO。

内核线程 1 还会再创建一个新的内核线程 2,并加载 /bin/sh 进程的代码。这就是 shell 程序,它用来接收用户的命令。也会展示我们熟悉的 shell 画面就展示出来了。

以上是我对闪客这本书中知识的一个概括。不过篇幅所限,不能把技术细节讲清楚。

早在今年 3 月的时候,我就收到了闪客发给我的书稿。看完过了这本纸质书的内容,并且还写了书封面中用到的推荐语。这本书非常巧妙地通过分析 Linux 0.11 的启动过程把所有内核相关的模块都给串了起来。

闪客的新书和飞哥的内容和书形成了很好的互补。我是侧重是针对Linux 3.10/6.1 版本网络管理、进程管理、内存管理等一些问题进行点状的突破。他的这本书是巧妙地通过分析 Linux 0.11 的启动过程把所有内核相关的模块都给串了起来。

基于 Linux 0.11 讲解 Linux 操作系统的启动原理_第2张图片

如果你也对 Linux 启动过程感兴趣,想深入地了解 Linux 的启动过程,也想了解各个模块是如何开始工作的,建议入手一本。

你可能感兴趣的:(linux,运维,服务器)