zoukankan      html  css  js  c++  java
  • 20169210《Linux内核原理与分析》第五周作业

    本次内容分为两部分,第一部分是实验,第二部分是教材的第四章和第六章。

    第一部分:实验
    本次的实验内容是构造一个简单的Linux系统MenuOS,过程如下。
    首先使用如下命令进入LinuxKernel

    $ cd LinuxKernel
    

    可以看到我们几个需要的文件,如Linux-3.18.6和rootfs生成了rootfs.img前面的工作已经做好了,就可以直接启动了,启动命令如下。

    $ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd roofs.img
    

    其中initrd是指定根文件系统,就是rootfs.img。
    启动结果如图所示,

    我们可以看到加载了根文件系统,init就执行起来了,就看到了MenuOS,内核启动完成后进入menu程序,支持三个命令help、version和quit。可以输入一个help,就可以看到三个命令。

    这样构件一个简单的Linux系统就完成了。

    接下来是使用gdb跟踪调试内核,命令如下

    $ qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd roofs.img —S -s
    

    先把内核启动一下,-S freeze CPU at startup (use ’c’ to start execution)是表示在CPU初始化之前就冻结起来,-s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项,是指在-gdb tcp::1234端口上创建了一个gdb server。结果如下图所示

    我们可以用水平分割另外打开一个窗口,输入

    $ gdb
    

    打开了gdb 就可以看到gdb的提示符,如图所示。

    使用如下命令把gdb带有符号表(debug信息)的内核镜像加载进来,就是在gdb界面中targe remote之前加载符号表。

    (gdb)file linux-3.18.6/vmlinux
    

    结果如图所示

    接下来就是使用如下命令建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行。

    (gdb)target remote:1234
    

    如图所示

    使用如下命令在内核启动的起点设置断点,断点的设置可以在target remote之前,也可以在之后。

    (gdb)break start_kernel
    

    如图所示

    如果按C加回车的话系统就开始启动了,启动到start_kernel的位置,如图所示

    输入s进入函数,输入n单步执行

    输入list就可以查看函数

    接下来简单分析一下start_kernel。

    其中&init_task是全局变量,即手工创建的PCB,0号进程即最终的idle进程。下面的debug boot等启动的点,都涉及到复杂的模块。不管分析内核的哪一个部分都会涉及到start_kernel,基本上所有的模块都是经过statr_kernel进行初始化。我们只看需要了解的。


    trap_init()是初始化一些中断向量。由于搜索该函数时遇到了问题,所以无法继续分析。具体问题如下图,找不到linux-3.18.6文件。

    只能了解到设置了很多硬件中断,其中有一个是trap_get()系统陷阱门。
    mm_init()是内存管理模块的初始化,sched_init()调度模块初始化等等还有很多模块的初始化。

    这是函数的最后一句。在该函数中有kernle_init,如下所示。

    kernel_thread(kernel_init, NULL, CLONE_FS);
    

    kernel_init()函数部分代码如下所示

    其中run_init_process()是linux系统中的1号进程,就是第一个用户态进程。
    接下来还创建了一个kthreadd内核线程,管理系统的资源,如下所示。

    pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
    

    rest_init()启动完成之后进入cpu_start_entry(),当系统没有进程需要执行时就调度到idle进程。cpu_start_entry()中的cpu_idel_loop()函数中的while(0)就是0号进程

    总结:
    rest_init()在内核启动一直存在,这就是0号进程,0号进程创建了一号进程kernel_init(),还创建了其他的服务线程。道生一一生二,二生三,三生万物。

    第二部分:教材
    本周学习了第四章进程调度和第六章内核数据结构。
    进程调度策略:I/O消耗型和处理器消耗型的进程分类,按进程优先级和时间片。
    Linux调度实现:时间记账,进程选择,调度器入口,睡眠和唤醒。
    链表:单项链表和双向链表,环形链表。还介绍了操作链表、沿链表移动和遍历链表的方法。
    对于队列介绍了kfifo,创建队列,推入队列数据,摘取队列数据,获取队列长度,重置和撤销队列。
    最重要的是自平衡二叉搜索树,一个平衡二叉搜索树是一个所有叶子节点深度差不超过1的二叉搜索树,一个自平衡二叉搜索树是指其操作都试图维持(半)平衡的二叉搜索树。红黑树是自平衡的二叉搜索树,并且遵循六个属性。
    1.所有的节点要么着红色,要么着黑色。
    2.叶子节点都是黑色。
    3.叶子节点都不包含数据。
    4.所有非叶子结点都有两个子节点。
    5.如果一个节点是红色,则它的子节点就是黑色。
    6.在一个节点到其叶子节点的路径上,如果总是包含同样数目的黑色节点,则该路径相比其他路径是最短的。
    上述条件,保证了最深的叶子节点的深度不会大于两倍的最浅叶子节点的深度,所以,红黑树总是半平衡的。

  • 相关阅读:
    QQ网页强制聊天,微博一键关注
    webpack(2) 安装和使用
    webpack(1) 为什么要用构建工具
    babel来进行js转换
    less实用语法
    elasticsearch笔记(8)聚合查询
    elasticsearch笔记(7) 复合查询_boolean查询 boolsting查询 filter查询
    elasticsearch笔记(6) 删除文档delete-by-query
    elasticsearch笔记(5) java操作es的查询_04深分页scroll查询
    elasticsearch笔记(4) java操作es的查询_04----- prefix查询 fuzzy查询 wildcard查询 range查询 regexp查询
  • 原文地址:https://www.cnblogs.com/crisgy/p/5990106.html
Copyright © 2011-2022 走看看