2018-2019-1 20189201《Linux内核原理与分析》第四周作业
1. 阴天☁️
你说你爱烟雨微茫,雨来时你却伞遮霓裳;
你说你爱春光灿烂,阳光普照时你却孑然惆怅;
你说你爱微风轻柔,风拂发梢时你却紧闭门窗;
这便是为何你说你也深深爱我,我却眼波成霜。
2. 今日发问,如何写博客。如何排版
一、书本第三章知识总结
- 计算机的三大法宝
- 存储程序计算机
- 函数调用堆栈
- 中断
- 操作系统的两把宝剑
- 中断上下文的切换——保存现场和恢复现场
- 进程上下文的切换
- Linux内核源码的目录结构如下所示。
- 关键的目录
- arch:arch目录在Linux内核目录中占比相当庞大,主要原因是arch目录中的代码可以使Linux
内核支持不同的CPU和体系结构。 - block:存放Linux存储体系中关于块设备管理的代码。
- crypto:存放常见的加密算法的C语言代码,譬如crc32、md5、sha1等。
- drives:驱动目录。
- fs:文件系统(File System)。
- init:init是初始化的意思,存放Linux内核启动时的初始化代码。
- ipc:Linux系统支持的IPC(进程间通信)的代码实现。
- kernel:存放内核本身需要的一些核心代码文件,其中有很多关键代码,包括pid——进程号等。
- lib:公用的库文件,里面是一些公用的库函数。需要注意的 是在内核编程中不能用C函数标准库函数。
- mm: 内存管理,存放Linux的内存管理代码。
- net:存放网络相关的代码,譬如TCP/IP的协议栈等。
- arch:arch目录在Linux内核目录中占比相当庞大,主要原因是arch目录中的代码可以使Linux
- 注意事项
- init目录下有main.c源文件,它是整个Linux内核启动的起点,但它的起点不是main函数,而是start_kernel
函数,start_kernel函数是初始化Linux内核启动的起点, start_kerne前的代码使用汇编语言来进行硬件初始化。 - qemu仿真kernel。
- bzImage是vmlinux经过压缩后的文件,是压缩的内核映像;vmlinux是编译出来的最原始的内核ELF文件。
- qemu命令中的-s、-S参数,-s表示用1234端口上的gdb-server连接,可以用-gdb tcp:xxxx来代替;-S表
示在CPU初始化之前冻结,使用c继续执行。
- init目录下有main.c源文件,它是整个Linux内核启动的起点,但它的起点不是main函数,而是start_kernel
- 几个函数
- init目录下的main.c函数
- start_kernel()函数
- init_task()函数
- rest_init()函数
二、实验部分
(1)跟踪分析Linux内核的启动过程
1. 内核运行
2. 重新运行,加上参数,内核被冻结
3. 调试内核
4. 设置断点到start_kernel
5. 设置断点到rest_init
6. 从 start_kernel 开始到 init 进程启动
···
-set_task_stack_end_magic()
为了检测栈溢出
-smp_setup_processor_id()
设置对称多处理器
-cgroup_init_early ()
初始化 Control Groups
-page_address_init()
页地址初始化(属于内存管理部分)
-setup_arch()
-build_all_zonelists()
-page_alloc_init ()
-setup_log_buf ()
初始化log 缓冲区(kernel/printk/printk.c)
-pidhash_init ()
初始化 pid 哈希表
-vfs_caches_init_early ()
-sort_main_extable ()
初始化中断向量
-mm_init ()
内存管理初始化
-sched_init ()
调度服务初始化
-rest_init()
剩余初始化
- kernel_init:init进程
- kthreadd:内核线程
- cpu_idle进程:代码中一直循环,如果系统中没有可执行的进程时,执行 idle 进程
···
(2)部分函数分析
1. rest_init()函数代码展示
···
static noinline void __init_refok rest_init(void)
{
int pid;
rcu_scheduler_starting();
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
kernel_thread(kernel_init, NULL, CLONE_FS);
numa_default_policy();
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
rcu_read_lock();
kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
rcu_read_unlock();
complete(&kthreadd_done);
/*
* The boot idle thread must execute schedule()
* at least once to get things moving:
*/
init_idle_bootup_task(current);
schedule_preempt_disabled();
/* 当系统没有进程需要执行时,就调度到idle进程 */
cpu_startup_entry(CPUHP_ONLINE);
}
···
2. start_kernel()分析:
lockdep_init(); //死锁检测模块初始化
debug_objects_early_init(); //初始化堆栈 此堆栈有额外的越界保护功能
page_address_init(); //初始化页表地址
pidhash_init(); //给新进程分配进程号
mm_init(); //初始化内存管理
sched_init(); //启动调度器
radix_tree_init(); //init some links before init_ISA_irqs() //初始化中断
三、实验收获与疑问
(1)收获
1. 线程与进程
- 进程:指在系统中能够独立运行并作为资源分配的基本单位,进程只能由父进程建立。
进程的个体是完全独立的,而线程间是彼此依存的。 - 线程:是进程中的一个实体,作为系统调度的基本单位。
- 多进程环境中,任何一个进程的终止,不会影响到其他进程。而多线程环境中,父线程
终止,全部子线程被迫终止(没有了资源)。而任何一个子线程终止一般不会影响其他线程
,除非子线程执行了exit()系统调用。任何一个子线程执行exit(),全部线程同时灭亡。可
以看出,进程和线程是包含的关系,对于书上内核线程的描述就更加迷惑了,又查找了关
于linux系统下的进程与线程相关资料: - 内核线程,只是一个称呼,实际上就是一个进程,有自己独立的TCB,参与内核调度,也
参与内核抢占。这个进程的特别之处有两点,第一、该进程没有前台。第二、永远在内核
态中运行。内核线程类似于用户进程,通常用于并并发处理性质的任务,并且可以抢占调
度。不同于用户进程,内核线程位于内核空间,并且可以访问内核函数和内核数据。
2. 针对于rest_init()函数来说,会启动三个进程,分别是idle(0号进程)、kernel_init(1号进程)、kthreadd(2号进程)。
(2)疑问
1. “gcc -o init linktable.c menu.c test.c -m32 -static –lpthread”执行这句话的时候gcc报错出现:找不到lpthread?
2018-2019-1 20189201《Linux内核原理与分析》第四周作业的更多相关文章
- 2019-2020-1 20199303<Linux内核原理与分析>第二周作业
2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...
- 20169219 linux内核原理与分析第二周作业
"linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业
1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...
- Linux内核原理与分析-第一周作业
本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...
- 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业
前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...
- Linux内核原理与分析-第二周作业
写之前回看了一遍秒速五厘米:如果
- 20169219linux 内核原理与分析第四周作业
系统调用 系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核唯一的合法入口. 一般情况下,应用程序通过在用户空间实现的应用编程接口(API)而不是直接通过系统调用来编程. 要访问系统调用 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第十三周作业
<Linux内核原理与分析>第十三周作业 一.本周内容概述 通过重现缓冲区溢出攻击来理解漏洞 二.本周学习内容 1.实验简介 注意:实验中命令在 xfce 终端中输入,前面有 $ 的内容为 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第十二周作业
<Linux内核原理与分析>第十二周作业 一.本周内容概述: 通过编程理解 Set-UID 的运行机制与安全问题 完成实验楼上的<SET-UID程序漏洞实验> 二.本周学习内容 ...
随机推荐
- Swagger如何测试Date类型参数
问题 Swagger测试时,参数直接输入日期格式化后的类型,会报参数日期转换错误 :ConversionFailedException 解决 网上说在参数上添加注解 @DateTimeFormat(p ...
- 压测过程中,获取不到redis连接池,发现redis连接数高
说明:图片截得比较大,浏览器放大倍数看即可(涉及到隐私,打了码,请见谅,如果有疑问,欢迎骚扰). 最近在压测过程中,出现获取不到redis连接池的问题 xshell连接redis服务器,查看连接数,发 ...
- centos安装node环境
一.安装wget yum install -y wget 二.下载node最新的安装包 wget https://nodejs.org/dist/v10.13.0/node-v10.13.0-linu ...
- np.array.all()和np.array.any()函数
np.array.all()是对np.array中所有元素进行与操作,然后结果返回True或False np.array.any()是对np.array中所有元素进行或操作,然后结果返回True或Fa ...
- 机器学习 - 正则化L1 L2
L1 L2 Regularization 表示方式: $L_2\text{ regularization term} = ||\boldsymbol w||_2^2 = {w_1^2 + w_2^2 ...
- CMDB服务器管理系统【s5day90】:API构造可插拔式插件逻辑
1.服务器端目录结构: 1.__init__.py from django.conf import settings from repository import models import impo ...
- 点评cat系列-应用集成
========================消息的基本属性========================消息的几个属性:type: 定义消息的 category, 比如 SQL 或 RPC 或 ...
- 使用ZooKeeper协调多台Web Server的定时任务处理(方案1)
背景说明: 有一套Web服务程序, 为了保证HA, 需要在多台服务器上部署, 该服务程序有一些定时任务要执行, 现在要保证的是, 同一定时任务不会在多台机器上被同时执行. 方案1 --- 任务级的主备 ...
- [物理学与PDEs]第1章第7节 媒质中的 Maxwell 方程组 7.2 媒质交界面上的条件
通过 Maxwell 方程组的积分形式易在交界面上各量应满足交界面条件: $$\beex \bea \sez{{\bf D}}\cdot{\bf n}=\omega_f,&\sex{\omeg ...
- 共通脚本utils
/** * 模块名:共通脚本 * 程序名: 通用工具函数 **/ var utils = {}; /** * 格式化字符串 * 用法: .formatString("{0}-{1}" ...