这周的任务主要分为两个方面,第一方面,学习MOOC网上视频第三讲并完成配套的实验。第二方面,学习课本的第四章和第六章。

首先从实验开始讲起,前期我们对Linux内核的源码做了一个简单的了解。包括Main函数是Linux内核运行的起点,具体是Start_kernel,就相当与C语言的Main函数。还介绍了一些和安全,网络,声音,脚本,和工具相关的包。包括介绍了一些Linux的历史和发展。



   接下来启动内核进入menu程序。

接下来要使用gdb跟踪调试内核.
vmlinux 它是是未压缩的内核,即编译出来的最原始的文件
用于kernel调试,产生system.map符号表,不能用于直接加载,
bzImage 压缩的内核映像
initrd 是在系统引导过程中挂载的一个临时根文件系统



这里的S是用来冻结cpu运行的,

s是用来指定端口的,若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项。

   这里需要再打开一个shell窗口,开始使用gdb跟踪调试内核。

(gdb) file linux-3.18.6/vmlinux #在gdb界面中targe remote之前加载符号表,打开gdb需要调试得文件。
将带有调试信息得linux镜像加载进来。
(gdb) target remote:1234#建立gdb和gdbserver之间的连接,按c 让qemu上的linux继续进行。
链接到我们刚才启动得冻结得linux系统。
(gdb)break start_kernel#断点的设置可以在target remote之前,也可以在之后。

按c之后开始启动内核。按n单步执行。s进入函数,finish结束掉当前函数。



list命令显示当前的代码。break可跳到自己需要观察的代码段!然后逐步的观察运行情况。







内核挂接根文件系统成功以后,将通过run_init_process()函数执行应用程序。这是一个尝试的过程,如果execute_command存在,则执行execute_command;如果不存在,则顺序执行/sbin/init、/etc/init、/bin/init、/bin/sh,直到有一个执行成功为止。如果都不存在,则会调用panic()上报错误。下面是kernel_init()函数:


static int __ref kernel_init(void *unused)
{
int ret; kernel_init_freeable();
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy(); flush_delayed_fput(); if (ramdisk_execute_command) {
ret = run_init_process(ramdisk_execute_command);
if (!ret)
return 0;
pr_err("Failed to execute %s (error %d)\n",
ramdisk_execute_command, ret);
} /*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
if (execute_command) {
ret = run_init_process(execute_command);
if (!ret)
return 0;
pr_err("Failed to execute %s (error %d). Attempting defaults...\n",
execute_command, ret);
}
if (!try_to_run_init_process("/sbin/init") ||
!try_to_run_init_process("/etc/init") ||
!try_to_run_init_process("/bin/init") ||
!try_to_run_init_process("/bin/sh"))
return 0; panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}

start_kernel()函数负责初始化内核各子系统,最后调用 rest_init(),启动一个叫作init的内核线程,继续初始化。在 init 内核线程中实现的功能很多,最重要的是负责完成挂接根文件系统、初始化设备驱动和启动用户空间的init进程等重要工作。

阅读课本的第四章和第六章。首先,在进程调度章节,结合本科期间操作系统的进程调度,对抢占式和非抢占式多任务,进程调度算法以及实现,抢占和上下文切换,实时调度策略这些概念有了全新的认识。

进程调度程序是确保进程能有效工作的一个内核子系统。

多任务操作系统就是能同时并发地交互执行多个进程的操作系统,期可以划分为两类:非抢占式多任务和抢占式多任务。Linux采用的是抢占式多任务。

进程分为I/O消耗型和处理器消耗型,调度策略通常要做到进程响应迅速和最大系统利用率。Linux更倾向于优先调度I/O消耗性进程。

Linux的进程优先级采用两种不同的优先级范围。第一种是用nice值,范围是从-20到+19,默认为0,nice值越高优先级越低;第二种是实时优先级,其值可配置,默认范围是从0到99,数值越大优先级越高,而且任何实时进程优先级都搞与普通进程。

Linux进程调度算法为CFS“完全公平调度算法(CFS)”,它是一个针对普通进程的调度类,算法实现定义在文件kernel/sched_fair.c中。Linux中并未直接分配时间片到进程,而是将处理器的使用比划分给了进程。CFS下每个进程获得的时间片的底线称为最小粒度,默认是1ms。

进程调度主要入口点是schedule(),在进程进行抢占和上下文切换时候都要调用它来完成的。抢占分为用户抢占和内核抢占。用户抢占发生在内核即将返回用户空间的时候即内核从系统调用返回用户空间或者从中断处理程序返回用户空间时,如果内核从检查到need_resched标志被设置,就会调用schedule()选择一个更适合的进程投入运行。Linux完整的支持内核抢占,即只要重新调度是安全的(没有持有锁),内核就可以在任何时间抢占正在执行的任务,内核抢占一般发生在中断处理程序正在执行且返回内核空间之前、内核代码在一次具有可抢占性的时候、内核中的任务显式调用了schedule()或者内核中的任务阻塞。

在内核数据结构章节,介绍了链表,队列,映射,二叉树等结构。然后在讲了他们在linux内核中的具体实现。这些知识点在本科期间的或多或少的涉及过一部分。结合本科期间的知识和现在的新资料,让我对计算机的内部结构和运行方式又加深了了解。数据结构我们之前都学过,本课讲的主要有链表、队列、映射和二叉树。我们都已经十分熟悉,只是在Linux下会有些许不同。

Linux内核中链表实现独树一帜,它不是将数据结构塞入链表,而是将链表节点塞入数据结构。简单来说,Linux内核是将prev和next两个指针封装成为一个list_head的结构体并塞入父结构结点,其中prev和next两个指针分别指向相邻结点的list_head结构体,通过宏container_of()从链表指针找到父结构中包含的任何变量


struct list_head{
struct list list_head *next;
struct list list_head *prev;
} struct fox{
unsigned long tail_length;
unsigned long weight;
bool is_fantastic;
struct list_head list;
}

容易看出链接起来的只是fox结构中的子结构list_head。

红黑树是一种自平衡二叉搜索树,具有特殊着色属性,或红或黑,有下面六个属性:


•所有节点要么着红色,要么着黑色;
•叶子节点都是黑色;
•叶子节点不包含数据;
•所有非叶子节点都有两个子节点;
•如果一个节点是红色,则它的子节点都是黑色;
•在一个节点到其叶子节点的路径中,如果总是包含同样数目的黑色节点,则该路径相比其他路径是最短的。

20169207《Linux内核原理与分析》第五周作业的更多相关文章

  1. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  2. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  3. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  4. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  5. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  6. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. B+树与B-树

    前面已经介绍过B-树,接下来,我们主要介绍一下B+树. 1.B+树的概念 B+树是应文件系统所需而生的一种B-树和变形树.一棵m阶B+树和m阶的B-树的差异在于: (1)有n棵子树的结点中含有n个关键 ...

  2. Android开发之使用GridView+仿微信图片上传功能(附源代码)

    前言:如果转载文章请声明转载自:https://i.cnblogs.com/EditPosts.aspx?postid=7419021  .另外针对有些网站转载本人的文章结果源码链接不对的问题,本人在 ...

  3. ES6 Proxy的应用场景

    一.相关API Proxy Reflect 二.Proxy应用场景 1.数据校验 表单提交的时候做数据校验,例如年龄是不是满足条件,数据类型是不是满足要求等等,这场场景非常适合使用Proxy. 下面展 ...

  4. PAT 1049 数列的片段和(20)(代码+思路分析)

    1049 数列的片段和(20)(20 分) 给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列{0.1, 0.2, 0.3, 0.4},我们有(0.1) (0.1, 0.2 ...

  5. 201621123008 《Java程序设计》第八周学习总结

    1. 本周学习总结 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 源代码: public boolean contains(Object o ...

  6. JSP自定义标签(标签处理器 tld文件)

    标签的形式如下,标签处理器就是处理JSP页面中的标签的属性和内容,定义好之后就跟使用JSTL一样 <标签名 属性名="属性值" 属性名="属性值"> ...

  7. Linux下文件的三种时间标记(atime ctime mtime)

    在windows下,一个文件有:创建时间.修改时间.访问时间. 在Linux下,一个文件有:状态改动时间.修改时间.访问时间. 1)查看文件(或文件夹)的三种时间标记 (stat 命令) Access ...

  8. Spring 属性注入(二)BeanWrapper 结构

    Spring 属性注入(二)BeanWrapper 结构 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) BeanWrap ...

  9. Spring ApplicationContext(八)事件监听机制

    Spring ApplicationContext(八)事件监听机制 本节则重点关注的是 Spring 的事件监听机制,主要是第 8 步:多播器注册:第 10 步:事件注册. public void ...

  10. Asterisk的type类型和身份认证

    Asterisk的type类型和身份认证 转载:http://zeevli.blog.163.com/blog/static/119591610201111745012380/ 在Asterisk中对 ...