软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 系统运维 -> linux内核启动过程追踪 -> 正文阅读
系统运维 最新文章
linux新进程的创建
Muduo网络库源码分析(一)EventLoop事件循
Linux系统分区
haproxylvsnginx负载均衡的比较
PeopleSoft介绍
win7+iis7+asp+.net+php环境配置
执行系统命令并且将输出写到指定日志文件的
linux批量替换多个文件中的字符串
makefile中=、:=和+=的区别
Linux服务器不关机新增硬盘的方法

[系统运维]linux内核启动过程追踪

  2016-04-03 20:46:13
慕课18原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”
一、使用自己的Linux系统环境搭建MenuOS的过程
  # 下载内核源代码编译内核
  cd ~/LinuxKernel/
  wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.18.6.tar.xz
  xz -d linux-3.18.6.tar.xz
  tar -xvf linux-3.18.6.tar
  cd linux-3.18.6
  make i386_defconfig
  make # 一般要编译很长时间,少则20分钟多则数小时
  # 制作根文件系统
  cd ~/LinuxKernel/
  mkdir rootfs
  git clone https://github.com/mengning/menu.git  # 如果被墙,可以使用附件menu.zip
  cd menu
  gcc -o init linktable.c menu.c test.c -m32 -static –lpthread
  cd ../rootfs
  cp ../menu/init ./
  find . | cpio -o -Hnewc |gzip -9 > ../rootfs.img
  # 启动MenuOS系统
  cd ~/LinuxKernel/
  qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
    //   -initrd file      Use file as initial ram disk.  
二、重新配置编译Linux使之携带调试信息
       在原来配置的基础上,make menuconfig选中如下选项重新配置Linux,使之携带调试信息
   kernel hacking—>[*] compile the kernel with debug info
     make重新编译(时间较长)
 
 三、使用gdb跟踪调试内核
  1、qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:
  // # -S freeze CPU at startup (use ’c’ to start execution)
  //# -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
  2、另开一个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 # 断点的设置可以在target remote之前,也可以在之后
四、过程图示:
  1、可以看到QEMU 已经运行而且被“冻结”。(有几个文件没有,不影响后续操作)
       

   2、另外打开一个窗口,进入linuxkernel目录,输入gdb 回车
    

   3、输入:(gdb)file linux-3.18.6/vmlinux
            (gdb)target remote:1234
        (gdb)break start_kernel
        

   4、输入c 回车,可以看到内核继续启动,最后停在了start_kernel处:
            

更多gdb指令:
显示和查找程序源代码
(1)list :显示10行代码,但是我为什么没有显示成功呢?
(2)list 5,10:显示源文件第五行到第十行的代码
(3)list t4.c:5,10:显示源文件中第五行到第十行的代码,在跳是含有多个源文件的次序时使用;
(4)list get_sum:显示get_sum函数周围的代码//什么叫周围的代码呢?
(5)list t4.c :get_sum:显示源文件t4.c中第五行到第十行的代码,在跳是含有多个源文件的次序时使用;
(6)如果在调试中运行linux命令,则可以在gdb的提示符下输入shell命令. (gdb)shell ls
(7)search forward用来从当前行向前查找第一个匹配的字符串;
           search get_sum   forward get_sum
(8)reverse_search 用来从当前行想前查找第一个匹配的字符串:  Example:  reverse_search main
设置和管理断点:
(1)以行号设置断点:(gdb)break 7
(2)以函数名设置断点:(gdb)break get_sum
(3)以条件表达式设置断点:方法一:break 行号或者函数名 if  条件.  Example:  (gdb)break 7 if i==99
                                      方法二:watch 条件表达式,下面是具体的举例:
                                      方法三:awatch;用来给表达式设置断点,在表达式的值发生改变或者表达式的值杯读取的时候,程序暂时停止;
  (4).查看当前设置的断点:info breakpoints
 (5)使用“disable  断点编号”命令可以是某个断点失效,程序运行到该段点时不会停下来而是继续运行。
 (6)使用“enable 断点编号”命令可以是某个断点恢复有效。
彻底的删除某个断点,可以使用clear或者delete命令。
(1)clear:删除程序中所有的断点;
(2)clear 行号:删除此行中的断点
(3)clear 函数名:删除该函数的断点
(4)delete 断点编号:删除指定编号的断点。如果一次要删除多个断点,各个断点编号以空格隔开。
控制程序的执行:
(1)continue命令:让程序继续运行,直到下一个断点或者运行完为止。格式:continue
(2)kill命令:用于结束当前程序的调试
(3)next和step命令
   区别:如果遇到函数,next会把函数调用当作一条语句来执行,再次输入next会执行函数调用后的语句;
   而step则会跟踪进入函数,一次一条的执行函数内的代码,直到函数内的代码执行完,在进行函数调用后的语句;
(4)nexti和stepi命令:用来单步执行一条机器指令,注意不是单步执行一条鱼据。单步执行一条语句使用next和step命令。通常一条语句有多条机器指令构成的。
   注意的是:gdb的一些命令可以简写,比如list可以用li来代替,continue命令可以用cont来代替。
  
  5、继续输入 list start_kernel 查看start_kernel函数为中心上下10行的代码
    然后接着输入list 查看后续的代码(每输入一次list,向后显示10行)
      

   我们继续输入list跟踪start_kernel以后的代码,看看后面的执行过程:
   

   

  

  

可以看到,在start_kernel之后是一大堆的初始化操作,初始化外设、时钟、寄存器等。后面还有很多操作,这里不作过多的截图展示,
  6、后面进入rest_init函数:
   

 四、总结:
  在start_kernel中调用了一系列的初始化函数,已完成内核本身的设置:设置与体系结构相关的环境、进程调度器初始化、控制台初始化、系统IRQ初始化、内存初始化等。在Start_kernel函数的最后调用了rest_init()函数,在rest_init中建立了init线程,并在最后调用cpu_idle()函数。
  可以这样理解:start_kernel最后clone出一个新的进程,也就是init进程,然后原来的进程就去执行cpu_idle()函数了,也就变成了idle进程,当发生一次进程调度后,init进程被调度运行。
  核心进程init()主要进行一些外设初始化的工作包括SMP(Symmetric Multi-Processing 对称多处理)的初始化,以及调用do_basic_setup()完成外设及其驱动程序的加载和初始化,当do_basic_setup()函数返回init() ,init() 又打开了、dev/console设备,重定向输出文件到控制台,最后通过kernel——execve加载执行init程序。
  追踪到init后可以修改文件系统,比如把显示的MENUOS修改为MYOS,修改quit指令,让其退出文件系统等:
      

    

    

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img
    //   -initrd file      Use file as initial ram disk.
  这里将-initrd 后面的参数rootfs.img加载到内存中运行,所以,这里的rootfs.img 可以随便改名字,因为内核代码中不会直接用这个名字而是通过initrd来传递的。再者rootfs.img是由tootfs文件夹打包得来的,而rootfs文件夹中只有一个init可执行文件,而init可执行文件来自于menu文件夹,menu文件夹中执行make指令会发现生成了一个test可执行文件,运行menu文件夹中的test和init后会发现效果是一模一样的,所以显然init是由test通过(cp test  init) 拷贝、重命名得来的,所以最终修改文件系统可以归结为修改menu文件夹中的main.c、test.c文件。
  在init/initramfs.c文件中:
       

上一篇文章      下一篇文章      查看所有文章
2016-04-03 20:46:11  
360图书馆 论文大全 母婴/育儿 软件开发资料 网页快照 文字转语音 购物精选 软件 美食菜谱 新闻中心 电影下载 小游戏 Chinese Culture
生肖星座解梦 三沣玩客 拍拍 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 天下美图 中国文化英文 多播视频 装修知识库
2017-1-19 18:50:39
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --