Ubuntu 16.04下搭建MenuOS的过程:

1、下载内核源代码编译内核

 1 # 下载内核源代码编译内核2 cd ~/LinuxKernel/3 wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz4 xz -d linux-3.18.6.tar.xz5 tar -xvf linux-3.18.6.tar6 cd linux-3.18.67 make i386_defconfig8 make # 一般要编译很长时间,少则20分钟多则数小时9
10 # 制作根文件系统
11 cd ~/LinuxKernel/
12 mkdir rootfs
13 git clone https://github.com/mengning/menu.git  # 如果被墙,可以使用附件menu.zip
14 cd menu
15 gcc -o init linktable.c menu.c test.c -m32 -static -lpthread
16 cd ../rootfs
17 cp ../menu/init ./
18 find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img
19
20 # 启动MenuOS系统
21 cd ~/LinuxKernel/
22 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

2、重新配置编译Linux使之携带调试信息

 1 $ sudo apt-get install ncurses-dev2 3 首先需要安装图形化调试工具ncurses,ncurses-dev是一个库,利用它就可以显示图形化的控制页面了。4 5 $ make menuconfig6 7 选择kernelhacking—>8 9 选择Comile-time checks and comp[iler options —>
10
11 按Y选中Compile the kernel with debug info
12
13 保存退出
14
15 重新make

3、使用gdb跟踪调试内核

1 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:
2 # -S freeze CPU at startup (use ’c’ to start execution)
3 # -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
4
5 另开一个shell窗口
6 gdb
7 (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表
8 (gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
9 (gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后

此时可以继续list接着向下查看,也可以step单步运行,或者利用汇编码ni(next instruction)逐指令地运行调试。

一些常用的gdb的命令:

(gdb) break n :在第n行处设置断点

(gdb) r:运行程序

(gdb) n:单步执行

(gdb) c:继续运行

(gdb) p 变量:打印变量的值

(gdb) bt:查看函数堆栈

(gdb) set args 参数:指定运行时的参数

(gdb) show args:查看设置好的参数

(gdb)delete 断点号n:删除第n个断点

(gdb)step:单步调试,若有函数调用,则进入函数(与命令n不同,n是不进入调用的函数的)

基础的工作就是这些,下面我尝试去分析一下内核从start_kernel到init进程启动的大体过程

使用list命令看到的start_kernel源码:

lockdep_init() : Linux有一个死锁检测模块lockdep,看注释说的是初始化hash表,应该是内核会依赖这个表来做其他的事。

set_task_stack_end_magic(&init_task) : init_task是一个全局变量,即是手工创建的PCB。 它是在Linux/init/init_task.c中被初始化的。具体的代码是

                       struct task_struct init_task = INIT_TASK(init_task);  那么task_struct应该就是一个类似于PCB结构的结构体,而INIT_TASK便是初始化该结构体的函数。

后面是一些模块的初始化,水平有限就不一一解释了,就说说老师提到的函数吧。

trap_init() : 初始化中断向量,设置一些中断门。

mm_init() : 内存管理模块的初始化。

sched_init() : 调度模块的初始化。

rest_init() : 源码如下:

static noinline void __init_refok rest_init(void)
394 {
395         int pid;
396
397         rcu_scheduler_starting();
398         /*
399          * We need to spawn init first so that it obtains pid 1, however
400          * the init task will end up wanting to create kthreads, which, if
401          * we schedule it before we create kthreadd, will OOPS.
402          */
403         kernel_thread(kernel_init, NULL, CLONE_FS);
404         numa_default_policy();
405         pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
406         rcu_read_lock();
407         kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
408         rcu_read_unlock();
409         complete(&kthreadd_done);
410
411         /*
412          * The boot idle thread must execute schedule()
413          * at least once to get things moving:
414          */
415         init_idle_bootup_task(current);
416         schedule_preempt_disabled();
417         /* Call into cpu_idle with preempt disabled */
418         cpu_startup_entry(CPUHP_ONLINE);
419 }

从rest_init开始,Linux开始产生进程,因为init_task是静态制造出来的,pid=0,它试图将从最早的汇编代码一直到start_kernel的执行都纳入到init_task进程上下文中。
第403行的kernel_init函数中有一个run_init_process函数,它的作用便是建立init_process进程,也就是Linux系统中的1号进程。它是第一个用户态进程。而从最后的cpu_startup_entry中可以看到init_task以后便成为了一个idle进程,也就是0号进程,当系统没有进程运行时,一直在运行这个空闲进程。

总结:通过本次试验,我对Liunx内核启动的过程有了大体的了解。内核启动时,会先进行一部分硬件的初始化,这部分是汇编语言完成的,而后会运行start_kernel,也就是内核的C语言部分。start_kernel会继续进行一些内核的初始化,建立0号进程,最后通过rest_init()建立1号进程,也就是第一个用户态进程,而以后0号进程便成为一个空闲(idle)进程,当没有其他进程运行时,系统便运行0号进程。总的来说,虽然明白了大体的过程,但还是感觉对于内核的了解只是浮于浅浅的表面,好像懂了点什么,又好像什么也不懂。希望继续深入的学习能够解答我的疑惑。同时也以此自勉吧。

鲍建竹 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 

转载于:https://www.cnblogs.com/strokes/p/6537446.html

实验三:跟踪分析Linux内核的启动过程相关推荐

  1. 实验三 Linux的启动与关闭,实验三:跟踪分析Linux内核的启动过程

    Ubuntu 16.04下搭建MenuOS的过程: 1.下载内核源代码编译内核 1 # 下载内核源代码编译内核 2 cd ~/LinuxKernel/ 3 wget https://www.kerne ...

  2. linux内核启动分析 三,Linux内核分析 实验三:跟踪分析Linux内核的启动过程

    贺邦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一. 实验过程 ...

  3. 实验三:跟踪分析Linux内核的启动过程 ----- 20135108 李泽源

    实验要求: 使用gdb跟踪调试内核从start_kernel到init进程启动 详细分析从start_kernel到init进程启动的过程并结合实验截图撰写一篇署名博客,并在博客文章中注明" ...

  4. linux内核分析作业3:跟踪分析Linux内核的启动过程

    内核源码目录 1. arch:录下x86重点关注 2. init:目录下main.c中的start_kernel是启动内核的起点 3. ipc:进程间通信的目录 实验 使用实验楼的虚拟机打开shell ...

  5. 通过gdb调试分析Linux内核的启动过程

    作者:吴乐 山东师范大学 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验流程 1.打开环境 执 ...

  6. 跟踪分析Linux内核5.0系统调用处理过程

    跟踪分析Linux内核5.0系统调用处理过程 学号384 原创作业转载请注明出处+中国科学技术大学孟宁老师的Linux操作系统分析 https://github.com/mengning/linuxk ...

  7. Bochs调试Linux内核6 - 启动过程调试 - 跳到bootsect引导程序执行

    接此,​​​​​​Bochs调试Linux内核5 - 启动过程调试 - 认识Bootsect.S_bcbobo21cn的专栏-CSDN博客 看一下,0x00007c11 这里是重复执行串传送:而后一条 ...

  8. linux启动过程剖析,分析Linux系统的启动过程

    导读 一直使用linux系统,却对系统启动过程及系统初始化和各种服务的启动不太清楚.今天终于搞明白整个是怎么一回事了.本来想自己写篇文章,刚好在网上看到一篇不错的介绍,很详细,就直接拿来了. Linu ...

  9. 实验三:跟踪分析Linux内核启动过程

    钟晶晶 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1.使用qemu ...

最新文章

  1. [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
  2. 26Exchange Server 2010跨站点部署-内外网邮件流测试
  3. thread.Join(); 让主线程等待自己完成
  4. 代码单元测试工具:gmock
  5. linux脚本转换exe,Ps1 To Exe(powershell脚本转换EXE工具) V3.0.6 官方版
  6. .NET+Sqlite如何支持加密
  7. javamail发送邮件的简单实例
  8. c语言三线程,如何用C语言实现多线程
  9. 怎样三天训练出AI围棋大师?教你AlphaGo Zero的3个trick
  10. 神经网络进行自然语言处理最佳实践
  11. 【转】LoadRunner使用Libmemcached与Memcached通讯
  12. MathType|强大的数学公式编辑器
  13. 核心指导网络由任务编码器_如何在现实世界中与实际用户一起指导您的编码和编码生涯...
  14. 量化交易入门--写第一个量化程序
  15. Windows 10 耳机插入前面板没反应的解决方案
  16. endless admin_认识Endless OS,轻量级Linux发行版
  17. 七分之一在线评论都有假,人工智能救一把?
  18. 自驱力超强的羊驼?斯坦福微调LLaMa
  19. 关爱老年人·守住养老钱
  20. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java洁强汽车美容nq941

热门文章

  1. rds 数据库营销报告_《营销自动化从入门到精通》第五章 集成营销自动化工具与CRM...
  2. android开发 解析 b5,张绍文android开发高手课读书笔记4-启动优化篇
  3. c# 指定打开某个路径下的CMD_Node.js 环境在 Windows 系统下安装与搭建教程
  4. cisco 模拟器安装及交换机的基本配置实验心得_看完这份1113页的TCP/IP协议+路由与交换机,成功上岸字节跳动...
  5. 如何在Python中将元素添加到列表
  6. 构造函数和复制函数java_用Java复制构造函数
  7. maven配置testng_TestNG Maven Surefire插件配置
  8. java初学者书籍_面向初学者的5本最佳Java核心书籍
  9. camerax_Android CameraX OpenCV图像处理
  10. 斯威夫特山地车_斯威夫特字典