一、内核空间和用户空间
为了彻底解决一个应用程序出错不影响系统和其它app的运行,操作系统给每个app一个独立的假想的地址空间,这个假想的地址空间被称为虚拟地址空间(也叫逻辑地址),操作系统也占用其中固定的一部分,32位Linux的虚拟地址空间大小为4G,并将其划分两部分:
-
0~3G 用户空间 :每个应用程序只能使用自己的这份虚拟地址空间
-
3G~4G 内核空间:内核使用的虚拟地址空间,应用程序不能直接使用这份地址空间,但可以通过一些系统调用函数与其中的某些空间进行数据通信
实际内存操作时,需要将虚拟地址映射到实际内存的物理地址,然后才进行实际的内存读写
二、执行流
执行流:有开始有结束总体顺序执行的一段独立代码,又被称为代码上下文
计算机系统中的执行流的分类:
执行流:
-
任务流--任务上下文(都参与CPU时间片轮转,都有任务五状态:就绪态 运行态 睡眠态 僵死态 暂停态)
-
进程
-
线程
-
内核线程:内核创建的线程
-
应用线程:应用进程创建的线程
-
-
-
异常流--异常上下文
-
中断
-
其它异常
-
应用编程可能涉及到的执行流:
-
进程
-
线程
内核编程可能涉及到的执行流:
-
应用程序自身代码运行在用户空间,处于用户态 ----------------- 用户态app
-
应用程序正在调用系统调用函数,运行在内核空间,处于内核态,即代码是内核代码但处于应用执行流(即属于一个应用进程或应用线程) ---- 内核态app
-
一直运行于内核空间,处于内核态,属于内核内的任务上下文 --------- 内核线程
-
一直运行于内核空间,处于内核态,专门用来处理各种异常 --------- 异常上下文
三、模块编程与应用编程的比较
| 不同点 | 内核模块 | 应用程序 |
|---|---|---|
| API来源 | 不能使用任何库函数 | 各种库函数均可以使用 |
| 运行空间 | 内核空间(3-4G) | 用户空间(0-3G) |
| 运行权限 | 特权模式运行 | 非特权模式运行 |
| 编译方式 | 静态编译进内核镜像或编译特殊的ko文件 | elf格式的应用程序可执行文件 |
| 运行方式 | 模块中的函数在需要时被动调用 | 从main开始顺序执行 |
| 入口函数 | init_module | main |
| 退出方式 | cleanup_module | main函数返回或调用exit |
| 浮点支持 | 一般不涉及浮点运算,因此printk不支持浮点数据 | 支持浮点运算,printf可以打印浮点数据 |
| 并发考虑 | 需要考虑多种执行流并发的竞态情况 | 只需考虑多任务并行的竞态 |
| 程序出错 | 可能会导致整个系统崩溃 | 只会让自己崩溃 |
四、内核接口头文件查询
大部分API函数包含的头文件在include/linux目录下,因此:
-
首先在include/linux 查询指定函数:grep 名称 ./ -r -n
-
找不到则更大范围的include目录下查询,命令同上
示例:

五、练习
什么是内核空间什么是用户空间 他们之间怎么传递的?
0~3G 用户空间 :每个应用程序只能使用自己的这份虚拟地址空间。非特权模式运行
3G~4G 内核空间:内核使用的虚拟地址空间,应用程序不能直接使用这份地址空间。特权模式运行
内核空间和用户空间之间进行数据传递,可以通过一些系统调用函数与其中的某些空间进行数据通信

![IntelliJ IDEA [警告] pom的依赖中出现警告Provides transitive vulnerable dependency](https://img-blog.csdnimg.cn/direct/8641198a2449456785a47ef7c07a952b.png#pic_center)

















