写点什么

Linux 内核系统结构

用户头像
林昱榕
关注
发布于: 2020 年 10 月 23 日

内核系统结构图

操作系统内核是一个庞大的系统工程,越大越复杂的系统就越需要架构设计,将复杂的大系统进行模块化分解,从而将大的复杂问题,变成若干相对小的简单问题。以子系统维度看,它的系统结构图,如下所示:





内核作用

内核把计算机资源管理起来,保护起来,然后通过系统调用这个服务窗口将这些资源分配给用户程序使用,对底层硬件和用户程序起到隔离和协调的作用,提升资源使用效率和程序开发者的开发效率。



系统调用

如上所述,要使用计算机资源,就必须知道怎么使用系统调用服务。下面是一些常见的系统调用。



进程管理

fork

创建进程使用fork。当父进程调用 fork 创建进程的时候,子进程将各个子系统为父进程创建的数据结构也全部拷贝了一份,甚至连程序代码也是拷贝过来的。

对于 fork 系统调用的返回值,如果当前进程是子进程,就返回 0;如果当前进程是父进程,就返回子进程的进程号。这样首先在返回值这里就有了一个区分,然后通过 if-else 语句判断,如果是父进程,还接着做原来应该做的事情;如果是子进程,需要请求另一个系统调用execve来执行另一个程序,这个时候,子进程和父进程就彻底分道扬镳了,也就产生了一个分支(fork)了。

execve

运行一个程序用execve。

waitpid

父进程可以调用它,将子进程的进程号作为参数传给它,这样父进程就知道子进程运行完了没有,成功与否。

内存管理

每个进程都有自己独立的内存空间,比如:代码段、数据段、堆、栈等。

brk/mmap

这里介绍两个在堆里面分配内存的系统调用,brkmmap。当分配的内存数量比较小的时候。当分配的内存数量比较大的时候,使用mmap,会重新划分一块区域。



文件管理

Linux 里有一个特点,那就是一切皆文件,包括二进制文件、文本文件、标准输入输出文件、管道、socket、设备、文件夹等都是文件。每个文件,Linux 都会分配一个文件描述符(File Descriptor),这是一个整数。有了文件描述符,我们就可以使用系统调用,查看或者干预进程运行的方方面面。“一切皆文件”的优势:统一了操作的入口,提供了极大的便利。



对于文件的操作,下面这六个系统调用是最重要的:

open

打开文件

close

关闭文件

creat

创建文件

lseek

打开文件以后,可以使用lseek跳到文件的某个位置

read/write

文件读写

信号处理

kill/SIGKILL/SIGSTOP

发送信号,终止进程

sigaction

注册一个信号处理函数

sem_wait/sem_post

抢占/释放信号量



进程间通信

msgget/msgsnd/msgrcv

通过msgget创建一个新的消息队列(在系统内核中),msgsnd将消息发送到消息队列,而消息接收方可以使用msgrcv从队列中取消息。

shmget/shmat

通过shmget创建一个共享内存块,通过shmat将共享内存映射到自己的内存空间,然后就可以读写了。共享内存存在“竞争”问题,通过信号量的机制 Semaphore解决。



网络通信

socket/bind/connect/accept/listen

我们可以通过 Socket 系统调用建立一个 Socket。Socket 也是一个文件,也有一个文件描述符,也可以通过读写函数进行通信。



Glibc

Glibc 为程序员提供丰富的 API,除了例如字符串处理、数学运算等用户态服务之外,最重要的是封装了操作系统提供的系统服务,即系统调用的封装。



每个特定的系统调用对应了至少一个 Glibc 封装的库函数,比如说,系统提供的打开文件系统调用 sys_open 对应的是 Glibc 中的 open 函数。



有时候,Glibc 一个单独的 API 可能调用多个系统调用,比如说,Glibc 提供的 printf 函数就会调用如 sys_open、sys_mmap、sys_write、sys_close 等等系统调用。

也有时候,多个 API 也可能只对应同一个系统调用,如 Glibc 下实现的 malloc、calloc、free 等函数用来分配和释放内存,都利用了内核的 sys_brk 的系统调用。



内核源码:https://www.kernel.org

发布于: 2020 年 10 月 23 日阅读数: 33
用户头像

林昱榕

关注

开心生活,努力工作。 2018.02.13 加入

还未添加个人简介

评论

发布
暂无评论
Linux内核系统结构