从BIOS到Bootloader与内核初始化

  • BIOS:基本输入输出系统(Basic Input and Output System),计算机在运行时,首先会进入BIOS。

  • Linux里的Grub2启动管理器用于系统启动(Grand Unified Bootloader Version 2)。Grub2第一个要安装的就是boot.img,它由boot.S编译而成安装到启动盘的第一个扇区,这个扇区通常称为MBR(Master Boot Record,主引导记录/扇区)。

  • Linux内核组成:内存管理子系统、进程管理子系统、设备子系统、文件子系统和网络子系统等。

  • 系统创建的第一个进程,称为0号进程。这是唯一一个没有通过for或者kernel_thread产生的进程,是进程列表的第一个。1号进程运行操作系统的第一个用户进程。

  • 为了兼容各种各样的文件系统,需要将文件的相关数据结构和操作抽象出来,形成一个抽象层对上提供统一的接口,这个抽象层就是虚拟文件系统VFS(Virtual File System)。

  • 操作系统将能够访问关键资源的代码放在Ring0权限,即内核态;将普通的程序代码放在Ring3权限,即用户态。处于保护模式的系统,当处于用户态的代码想要直接执行更高权限的指令,这种行为被禁止。(Ring1和Ring2放置着设备驱动的代码)

  • 用户态的代码访问核心资源需要通过系统调用提供的统一入口。当用户态的程序运行时,要访问一个核心资源,如访问网卡发一个网络包,需要暂停当前的运行,调用系统调用,然后轮到内核中的代码运行。内核将从系统调用传过来的包,在网卡上排队,轮到的时候就发送。发送结束后,系统调用就结束,返回用户态,让暂停运行的程序继续运行。

  • execve是一个系统调用,它的作用是运行一个执行文件,即执行程序。do_execve往往是内核系统调用的实现。

  • 文件系统一定是在一个存储设备上,Linux访问存储设备,要有驱动才能访问。内存访问不需要驱动,ramdisk是一个基于内存的文件系统,是根文件系统。运行ramdisk上的/init结束后,就处于用户态。/init会先根据存储系统的类型加载驱动,有了驱动就可以设置真正的根文件系统,有了真正的根文件系统,ramdisk上的/init会启动文件系统上的init。

  • 函数kthreadd,负责所有内核态的线程的调度和管理,是内核态所有线程运行的祖先。

  • 内核的启动从入口函数start_kernel()开始。
    ->>通过INIT_TASK(init_task)产生第一个进程,即0号进程。
    ->>trap_init()初始化系统调用。
    ->>mm_init()用来初始化内存管理。
    ->>sched_init()用于初始化调度模块。
    ->>vfs_caches_init()用来初始化基于内存的文件系统rootfs。
    ->>rest_init()用来做其他方面的初始化,包括:
    ->>用kernel_thread()创建第二个进程,即1号进程,它是用户态进程的祖先;
    ->>用kernel_thread()创建第三个进程,即2号进程,它是内核进程的祖先。

  • 从内核态来看,无论是进程,还是线程,我们都可以统称为任务,都使用相同的数据结构,平放在同一个链表中。

猜你喜欢

转载自www.cnblogs.com/kongzimengzixiaozhuzi/p/13201511.html