第三周:构造一个简单的LINUX系统MENUOS

发布时间:2021-10-20 02:42:39

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

一、Linux内核源码简介

1.操作系统的两把宝剑


? 中断上下文的切换??保存现场&恢复现场? 进程上下文的切换

2.Linux内核源代码简介


(1)打开内核源代码页面


? arch/目录:支持不同CPU的源代码;其中的X86是重点? init/目录:内核启动相关的代码基本都在该目录中? start_kernel函数就相当于普通C程序的main函数kernel/目录:Linux内核核心代码在kernel目录中

(2)README


提供内核的各种编译方法、生成文件的查看方法。例如:


? INSTALLING 如何安装内核源代码? make mrproper 清理安装时生成的中间代码
二、构造一个简单的Linux系统

1. 运行MenuOS系统


在实验楼的虚拟机环境里,打击打开shell,使用下面的命令



cd LinuxKernel/

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

# -initrd:指明一个根文件系统



启动实验的Linux系统MenuOS,实际上就是一个在Linux内核的基础上,再运行一个简单菜单命令行程序。

在MenuOS>的提示符下输入help,看到其全部支持的命令:



help、version、quit

2. 使用gdb跟踪调试内核

使用带参数命令启动MenuOS,使得系统在刚启动时,暂停等待调试器跟踪执行。



qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
# -S 在CPU初始化之前,冻结CPU
# -s 1234端口上创建一个tcp接口。若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项

另开一个shell窗口,启动gdb。



(gdb)file linux-3.18.6/vmlinux
# 在gdb界面中targe remote之前加载符号表
(gdb)target remote:1234
# 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
(gdb)break start_kernel
# 在start_kernel函数入口处设置断点
(gdb)c
# 使得系统运行到start_kernel处停住
(gdb)list
# 显示当前行所在位置上下的代码


?


三、简单分析start_kernel
(1)全局变量 init_task

全局变量init_task,即手工创建的PCB,0号进程初始化,0号进程就是最终的idle。



500asmlinkage __visible void __init start_kernel(void)
501{
502 char *command_line;
503 char *after_dashes;
504
505 /*
506 * Need to run as early as possible, to initialize the
507 * lockdep hash:
508 */
509 lockdep_init();
510 set_task_stack_end_magic(&init_task);//init_task即手工创建的PCB,0号进程及最终的idle进程
511 smp_setup_processor_id();
512 debug_objects_early_init();

(2)初始化一些中断向量 trap_init()


中断向量表的初始化函数,设置了很多中断门(Interrupt Gate)


set_intr_gate:设置中断门



(3)内存管理模块初始化 mm_init()


(4)调度模块初始化 sched_init()


函数内做了很关键的一步初始化??对0号进程,即idle进程进行初始化。


(5)其它模块初始化 rest_init()


kernel_thread(kernel_init,NULL,CLONE_FS)中的kernel_init包含一个run_init_process,创建了一号进程,即第一个用户态进程。之后创建了kthreadd,一个内核线程来管理系统的资源。


?


? 创建了一号进程后,kernel_thread函数通过405行的kthreadd管理线程;? 由cpustartupentry(CPUHPONLINE);??>cpuidleloop();??>static void cpuidle_loop(void):? cpuidleloop中有一个while循环,当start_kernel启动之后,她就一直存在。当系统没有进场需要执行的时候就调度到idle进程

四、总结


1.kernelthread是0号进程,它创建了1号进程kernelinit,以及它的一些服务的内核线程,这样整个系统及启动起来了;


2.然后init进程会再启动一些进程。


?



转载于:https://www.cnblogs.com/lv-20135229/p/5272516.html






相关资源:2020深圳杯C题.docx

相关文档

  • 种植西红柿的方法与西红柿的功效
  • 迪奥口红海报图
  • 青年教师的职业规划范文
  • 银行存款常用英语
  • 手机耳机插电脑会坏吗
  • 科目二考试反光镜看点技巧
  • 冒烟测试流程图和测试数据准备
  • 什么的电脑填上适合的词
  • 区块链&比特币学习笔记
  • GO桌面拦截偷放图标怎么设置?
  • 山东幼教专升本可以考哪些学校
  • 勇敢的成长随笔400字
  • CentOS6.5环境下OpenSSL实战:自己搭建CA中心,申请,签发,吊销,导入证书,SSL 握手详解...
  • 简述斯宾塞的实科教育思想
  • 关于植树节活动工作总结范例
  • 【npm】npm start 修改启动端口的不同方式
  • 店铺英语表达汇总
  • 递归函数(1到100的累加)
  • 酷比s301t怎么ROOT
  • Hadoop开发---经验总结1
  • 关于南京博物院游记作文400字
  • 少儿应该怎样学英语口语
  • 男人结婚不到一年出轨了怎么办
  • 社会流行文明风 关于文明作文800字
  • 国徽
  • 中秋节的经典句子
  • 外校德育管理工作考察报告
  • 拉着流年,好好的说再见
  • 开车跑偏是什么原因汽车跑偏需要做动平衡吗
  • 超市中秋节标语
  • 猜你喜欢