内核是一个模块化、分层的操作系统内核,它充当硬件和用户空间程序之间的桥梁。其架构旨在提供高效、稳定和可扩展的操作系统。

内核的核心组件包括:

  • 系统调用接口: 应用程序与内核通信的接口。

  • 调度程序: 管理进程执行并分配 CPU 时间。

  • 内存管理单元 (MMU): 管理虚拟内存和物理内存之间的映射。

  • 虚拟文件系统 (VFS): 提供对不同文件系统的一致访问。

  • 网络堆栈: 处理网络通信。

内核还包含一系列子系统,它们提供特定的功能:

  • 设备驱动程序: 与硬件设备交互。

  • 文件系统: 提供对文件和目录的访问。

  • 网络协议栈: 实现特定网络协议,如 TCP/IP。

  • 安全模块: 处理安全功能,如访问控制和加密。

  • 系统服务: 提供系统级服务,如计时器和进程间通信。

用户空间程序通过系统调用与内核交互。系统调用是内核提供的特殊函数,允许用户空间程序执行受保护的操作,例如访问文件或分配内存。

内核通过中断与硬件设备交互。当硬件设备需要内核的关注时,它会引发中断。内核然后处理中断并采取适当的行动,例如处理网络数据包或更新设备状态。

二、进程基础知识

Linux 内核把进程称为任务(task),进程的虚拟地址空间分为用户虚拟地址空间和内核虚拟地址空间,所有进程共享内核虚拟地址空间,每个进程有独立的用户虚拟地址空间。

进程有两种特殊形式:

  • 没有用户虚拟地址空间的进程称为内核线程。

  • 共享用户虚拟地址空间的进程称为用户线程。

通常在不会引起混淆的情况下把用户线程简称为线程。共享同一个用户虚拟地址空间的所有用户线程组成一个线程组。

C 标准库进程术语和 Linux 内核进程术语对应关系如下:

C 标准库进程术语

Linux 内核进程术语

包含多个线程的进程

线程组

只有一个线程的进程

进程或任务

线程

共享用户虚拟地址空间的进程

三、Linux 进程四要素

  1. 有一段程序供其执行。

  2. 有进程专用的系统堆栈空间。

  3. 在内核有 task_struct 数据结构。

  4. 有独立的存储空间,拥有专有的用户空间。

四、task_struct 数据结构主要成员

(include/linux/sched.h)

展开

代码语言:C

自动换行

AI代码解释


struct task_struct {//进程描述符 #ifdef CONFIG_THREAD_INFO_IN_TASK /* * For reasons of header soup (see current_thread_info()), this * must be the first element of task_struct. */ struct thread_info thread_info; #endif unsigned int __state;//指向进程状态 #ifdef CONFIG_PREEMPT_RT /* saved state for "spinlock sleepers" */ unsigned int saved_state; #endif /* * This begins the randomizable portion of task_struct. Only * scheduling-critical items should be added above here. */ randomized_struct_fields_start void *stack;//指向内核栈 refcount_t usage; /* Per task flags (PF_*), defined further below: */ unsigned int flags; unsigned int ptrace; // ...... };

  • task_struct:进程描述符。

  • __state:指向进程状态。

  • *stack:指向内核栈。

  • pid:指向全局的进程号。

  • tgid:指向全局的线程组的标识符。

  • *real_parent:指向真实的父进程

  • *parent:指向当前的父进程。比如一个进程被另外的进程使用系统调用进行跟踪(ptrace),那么此时的父进程就是跟踪进程。

  • 进程调度策略的优先级:prio、static_prio、normal_prio、rt_priority。

  • nr_cpus_allowed:允许进程在哪些处理器上执行。

  • *mm:指向内存描述符,内核线程此项为NULL。

  • *active_mm:指向内存描述符,内核线程运行时从进程借用。

  • *fs:文件系统信息。

还有很多成员,这里就不一一列举。

五、创建新进程分析

在 Linux 内核中,新进程是从一个已经存在的进程复制出来的,内核使用静态数据结构造出 0 号内核线程,0 号内核线程分叉生成 1 号内核线程和 2 号内核线程(kthreadd 线程)。1 号内核线程完成初始化以后装载用户程序,变成 1 号进程,其他进程都是 1 号进程或者它的子孙进程分叉生成的;其他内核线程是 kthreadd 线程分叉生成的。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐