os       

os

内核初始化

  1. 初始化进程列表(虚拟的0号进程,项目模版)

  2. trap_init

  3. mm_init

  4. sched_init

  5. vfs

  6. 初始化1号进程,用户态进程的祖先,内核中准备好用户态寄存器

  7. 初始化2号进程,内核进程的祖先

image-20200422114722529

进程上下文切换主要干两件事情,一是切换进程空间,也即进程的内存,二是切换寄存器和 CPU 上下文

linux的 0号进程 和 1 号进程

Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2)

* idle进程由系统自动创建, 运行在内核态

idle进程其pid=0,其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。完成加载系统后,演变为进程调度、交换

* init进程由idle通过kernel_thread创建,在内核空间完成初始化后, 加载init程序, 并最终用户空间

由0进程创建,完成系统的初始化. 是系统中所有其它用户进程的祖先进程 Linux中的所有进程都是有init进程创建并运行的。首先Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。在系统启动完成完成后,init将变为守护进程监视系统其他进程。

* kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间, 负责所有内核线程的调度和管理

它的任务就是管理和调度其他内核线程kernel_thread, 会循环执行一个kthread的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread, 当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程

进程

image-20200423175411690

image-20200423175315587

内存页块

把所有的空闲页分组为 11 个页块链表,每个块链表分别包含很多个大小的页块,有 1、2、4、8、16、32、64、128、256、512 和 1024 个连续页的页块。最大可以申请 1024 个连续页,对应 4MB 大小的连续内存。每个页块的第一个页的物理地址是该页块大小的整数倍。

image-20200422180654728

把物理页面分成一块一块大小相同的页,这样带来的另一个好处是,当有的内存页面长时间不用了,可以暂时写到硬盘上,我们称为换出。一旦需要的时候,再加载进来,就叫作换入。这样可以扩大可用物理内存的大小,提高物理内存的利用率。在内核里面,有一个进程 kswapd,可以根据物理页面的使用情况,对页面进行换入换出。

为了能够定位和访问每个页,需要有个页表,保存每个页的起始地址,再加上在页内的偏移量,组成线性地址,就能对于内存中的每个位置进行访问了

image-20200422220557850

文件系统

image-20200423083524266

进程通信

管道

消息队列

共享内存

信号

网络

image-20200423175144670

image-20200423175129063

数据中心

image-20200423104230028

参考

https://time.geekbang.org/column/article/120928

https://www.cnblogs.com/alantu2018/p/8526970.html