写在最前面的话:

后面的一系列博客主要围绕MIT-OS的学习课程来创建;

为什么会学习mit-os?
   1)对于复杂的事物,一种常见的思维就是从简单到复杂的思维。根据这种思维去学习原始的os,透过它去熟悉os的基本概念与核心构造,从而以此作为基础去学习现代os的各项技术,能够去更新创造与优化它们。
   2)一种典型的西方逻辑思维——原子思想,所有系统都是可以分解为原子结构,然后有序的组合;根据这种思维,很容易将os分割成若干流程或者若干结构的有序组合;而且在学习过程中,发现这种课程是很好的学习模板,它通过代码的方式去引导学习去实现相关的流程与结构,这样更有利于掌握与学习学习内容。
   3)从一个更完整的角度去学习os,因为os是最贴近硬件,所以需要接触硬件的相关知识,特别是处理器的软件参考手册,从一个狭窄的角度会发现,os是处理器的软件驱动;对于os,个人认为一定需要自己尝试去实现相关部分流程或者模块,同时去调试os,才能更与os贴近,从而得到更深刻的理解。

具体课程可以到如下网址参考:http://pdos.csail.mit.edu/6.828/2012/schedule.html

俗话说得好磨刀不误砍柴工,有了好刀才能势如破竹的砍柴;也只有当把工具与环境有更好,更深的认识,才能将系统的知识有效的模拟与调试,才能将书本上的知识带入到实际工程中来;以工程的态度去对待所学到的知识,将理论与实践相结合,从而对概念有更深入的理解。

从某种角度来说,对于代码或者软件来说,更多的是经验的累计与总结;而且它很实在,它可以实现自己的思想,同时也能够被直观的看到与仿真,说白了,就是任何代码或者最好是能够运行它,然后调试它,从实际运行过程中去体会它的意义,从而能够更好的理解,然后被直接使用。目前最常用的代码分析方法,就是看源代码,这样静态的去分析与理解,这种方式很直观而且有效,但是它只是停留在逻辑层面,忽略了实实在在运行环境,这样很容易只是理解思想,很难对学习者有更好的启发与提升;所以我的建议是,任何代码都请去调试它,或者自己去实现它,在模拟环境中调试之。

对于操作系统的调试,目前有现成的解决方案就是用虚拟机去运行之,透过虚拟机平台去调试它;所以对于MIT—OS的实验课程所需要的工具与环境就是虚拟机。当然,以此作为平台,我们也可以去调试linux的内核。还有需要了解的一种工具就是链接源代码与系统的工具——编译器。所以我们会从如下2个方面去准备我们的工具与实验环境,1个实验环节来展示它们的力量。

前面两个方面可以参考如下的部分:http://pdos.csail.mit.edu/6.828/2012/tools.html

一)虚拟机——qemu

为什么要选择它呢?开源,而且功能强大——不仅能完全模拟pc环境,效率高,更重要的是它能与gdb调试工具直接进行交互,进行系统调试。其他更多的了解可以到官网http://wiki.qemu.org/Main_Page。当然它有很多的用处,但对于目前我们来说,更多是熟悉它的使用,能够运行我们的os,然后去调试之。

1.下载源码:从官网http://wiki.qemu.org/Download,解压缩它。

2.编译它,为了防止仿真的系统直接将我们的终端给控制了,所以我建议编译一个带简单窗口的版本,这样更方便我们调试系统——所以我用的是SDL的图形界面的——因为它足够简单。

a)解决依赖关系如下:

qemu -->zlib

-->glib-->libffi

-->sdl

最新的qemu依赖于zlibglibsdl,同时glib依赖libffi。所以为了成功编译qemu,需要提前编译安装如上4个包,编译方法就是linux的源码安装3步曲——configuremakemake install

b)配置编译参数:

 ./configure --target-list=i386-softmmu,x86_64-softmmu --enable-sdl --with-sdlabi=2.0 --enable-debug –-prefix=$YROOT

因为我们主要模拟x86环境中的实现,所以我们只需要支持的虚拟机器构架为--target-list=i386-softmmu,x86_64-softmmu,当然如果需要支持其他构架的实现,也可以添加其他的;支持sdl图形窗口:--enable-sdl --with-sdlabi=2.0;将qemu建议安装到我们的实验环境——由环境变量决定YROOT

c)编译与安装:

make && make install

d)生成使用文档——html版本:qemu-doc.html

make html

因为生成时,有依赖关系:makeinfo-->textinfo.

3.常用的使用命令,汇总如下:如需要更详细的参考可以用qemu-doc.html或者从官网获取http://wiki.qemu.org/Manual。如下的描述很多从qemu-doc.html摘取,而且以i386平台的工具使用,同时我们也主要使用它。

a)基本使用方式:

qemu-system-i386 [options] [disk_image]

options为控制参数。

disk_image为仿真使用的磁盘镜像,就像我们电脑使用的硬盘。

b)处理器与内存的参数:

-smp X :处理器核数,比如双核:-smp 2

-m Y:内存大小,比如1G:-m 1G

c)硬盘添加:

-hdX(a-d)file:添加磁盘镜像文件,比如:-hdb basic.img

d)不是用图形窗口:

-nographic:默认qemu是会使用图形窗口,如果不是用则禁用之,它会在调试linux用到,qemu保存log到文件的功能没有用。

e)保存debug系统信息到文件:

-d xxx -Dfile:调试系统的xxx信息到文件file,比如:查看系统的反汇编——qemu-system-i386 -d in_asm -D test-d

当然可以查看系统的其他信息: qemu-system-i386 -d help

f)添加串口:

-serial xxx:给系统添加调试串口,这在系统调试中很重要,比如:添加当前终端为串口——-serial stdio。当然也可以查询其他的串口:qemu-system-i386 -serial [TAB][TAB]

g)停止处理器:-S

h)设置gdb调试:-gdb tcp::port;使用tcp端口进行调试。这实际上就模拟了嵌入式linux系统的gdb远程调试。详细步骤可以参考《qemu-doc.html3.12 GDB usage》:当然可以参考之前我的博客关于gdb的使用。快捷gdb调试设置:-s(等价于-gdb tcp::1234)。

i)监视器的使用:

-monitor xxx;使用qemu监视器,通过它可以发现系统的状态,同时动态配置系统,极大的方便了系统调试。但是我们没有用。

j)直接启动linux

qemu-system-i386 -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda"

-kernel直接加载内核,-append为添加给内核的参数。

二)交叉编译工具

为什么需要交叉编译工具呢?目前我们有最多的参考资料,最成熟的技术,是建立在x8632位系统中的,但是目前我们电脑已经到了64位,所以我们需要在64位系统中编译出32位运行系统,这样尽可能方便调试系统。而对于64位系统或者其他处理器——比如:ARM,可以看作是系统的扩展与移植,当我们熟悉x8632位系统中,就可以将某些概念与技术进行推广,然后通过差异化去理解相关的概念。

网上有很多交叉编译工具的编译方法,都是我们的参考,但是能不能成功,这就需要自己动手实验了。

如下所描述的内容都是参考,只有自己动手去尝试才能保证其正确性,因为每个人的实验环境不一样。

所以如下为老生常谈的内容,同时交叉编译工具的制作是很麻烦的,而且需要很多配置的信息,大都需要详细参考gcc官网的相关编译注释,从而我们为了简化这个流程,同时保证制作的稳定性,将相关的编译部分制作成脚本,来自动生成相关工具。在我的博客对应的资源中有脚本的实现,其中有较详细的注释,保证能够编译成功。

参考文档:

官方文档:https://gcc.gnu.org/install/

编译测试结果:https://gcc.gnu.org/ml/gcc-testresults/2015-05/msg00687.html

另外一个有效的参考文档为lfs(Linux From Scratch)相关编译步骤,其中也包含了交叉编译工具的制作——只不过它是在模拟root的方式下实现的:

从如下网址,下载最新的参考文档:http://www.linuxfromscratch.org/lfs/download.html

编译步骤如下:

1.下载源码:

gcc-->glibc   -->glibc-ports,mpfr,mpc,gmp,islkernel头文件

-->binutils

因为编译器gcc依赖glibcbinutils,而glibc又依赖于glibc-ports,mpfr,mpc,gmp,islkernel头文件。

所以需要到各自的官网上下载最新的源代码即可,然后放到目录tools-src路径下。

2.设置与创建编译,安装环境:

ctools_instl_path=`pwd`/tools----工具安装路径

#编译根目录

compile_top=`pwd`/build------编译的路径

ctarget=i486-yiye-linux------目标主机的构架,格式如下:处理器构架-制造商-运行os

glibc_instl_path=$ctools_instl_path/$ctarget--glibc安装路径

sysroot_path=$glibc_instl_path----系统的模拟根路径

根据如上配置我们编译出来的交叉工具为:i486-yiye-linux-gcc,然后根据如上目录创建对应的目录。不能使用i386来标记处理器构架,因为glibc已经认为i386构架过时了,至少需要i486构架,但是不影响我们描述与使用。

3.以如下的步骤编译所有源码:

install_kernel_headers-------编译与安装内核头文件

install_binutils--------编译与安装binutils工具

install_gcc_step1------第一遍编译与安装gcc

install_glibc---------编译与安装glibc

install_gcc_step2-------第二遍编译与安装gcc

如上所述,gcc被编译了两次,第一次编译是为了编译glibc,第二次编译是为了gcc能够引用我们编译出来的gcc;详细的安装步骤与解释请参考我的脚步,主要是很多细节需要去设置,当然有时可能需要去查看相关源代码,根据官方文档去猜测其真实用途。唯一一个需要多次调整gcc的使用相关库的路径。

4.脚本的使用:

./auto_compile.sh tools-src

然后就会生成交叉编译工具了,如下是我编译的5.1.0i486-yiye-linux-gcc的相关路径。

tools/

├── qemu

│   ├── glib-2.44.0

│   ├── qemu-2.3.0

│   ├── texinfo-5.2

│   └── zlib-1.2.8

├── sdl

│   └── SDL2-2.0.3

├── sources

│   ├── binutils-2.25.tar.gz

│   ├── gcc-5.1.0.tar.bz2

│   ├── glibc-2.21.tar.xz

│   ├── glibc-ports-2.16.0.tar.xz

│   ├── gmp-6.0.0a.tar.xz

│   ├── isl-0.14.tar.bz2

│   ├── linux-4.0.2.tar.xz

│   ├── mpc-1.0.3.tar.gz

│   └── mpfr-3.1.2.tar.xz

├── test

│   ├── a.out

│   ├── binutils-2.25

│   └── main.c

└── tools

├── bin

├── i486-yiye-linux

├── include

├── lib

├── lib64

├── libexec

└── share

编译出来的版本测试如下:

[yiye@yiye pc_prj]$ i486-yiye-linux-gcc -v

Using built-in specs.

COLLECT_GCC=i486-yiye-linux-gcc

COLLECT_LTO_WRAPPER=/home/yiye/study/pc_prj/tools/tools/libexec/gcc/i486-yiye-linux/5.1.0/lto-wrapper

Target: i486-yiye-linux

Configured with: ../gcc-5.1.0/configure --prefix=/home/yiye/study/pc_prj/tools/tools --target=i486-yiye-linux --with-sysroot=/home/yiye/study/pc_prj/tools/tools/i486-yiye-linux --with-build-sysroot=/home/yiye/study/pc_prj/tools/tools/i486-yiye-linux --with-local-prefix=/home/yiye/study/pc_prj/tools/tools/i486-yiye-linux --with-native-system-header-dir=/include --disable-nls --enable-shared --disable-static --enable-languages=c,c++ --enable-__cxa_atexit --enable-c99 --enable-long-long --enable-threads=posix --disable-multilib --with-system-zlib --enable-checking=release --enable-libstdcxx-time

Thread model: posix

gcc version 5.1.0 (GCC)

三)单步调试linux内核

为什么要调试linux内核?一个很直接的原因就是梳理内核的启动流程与调试内核的关键流程,能够对内核进行动态分析,不仅仅停留在静态分析上,更深入去理解内核。推荐一个查看内核源代码的工具——LXRhttp://lxr.oss.org.cn/ident

我们以如下步骤进行调试:

1.下载内核:最新内核www.kernel.org

2.配置内核:

make CROSS_COMPILE=i486-yiye-linux- ARCH=i386 menuconfig

3.编译内核:

make -j8 && make install

4.制作根文件系统镜像,因为内核启动过程中,需要一个根文件系统,同时也是为了制作基于linux的最小系统进行调试。制作根文件系统可以参考《Embedded Linux Primer: A Practical, Real-World ApproachChapter 6. System Initialization。详情见博客资源。因为制作根文件系统是一个比较麻烦的过程,所以我也创建了一个脚本自动生成硬盘镜像;详情见附件:create-simple-root.sh.一定要以root方式来运行。

linux环境下制作根文件镜像,需要如下工具:

a)创建镜像文件

dd if=/dev/zero of=disk.img bs=1m count=512

b)将镜像与设备联系起来

loseup -f disk.img

loseup /dev/loop0 disk.img

c)对设备文件进行分区

fdisk /dev/loop0

d)读取镜像文件的分区信息

kpartx -a /dev/loop0

f)对分区格式化

mkfs /dev/mapper/loop0p1

g)安装grub

grub-install --target=XXX --boot-directoty=YYYY /dev/loop0

h)挂载设备loop

mount -t extX /dev/mapper/loopXpY YYY

i)卸载

umount YYY

kpartx -d /dev/loop0

loseup -d /dev/loop0

制作根文件系统的相关内容:

根文件系统需要一个简单的工具集,所以busybox能够帮上忙了。所以需要下载最新的busyboxhttp://www.busybox.net/编译方法和内核一样。

然后以如下步骤创建最小的根文件系统:

a)创建基本文件系统目录

mkdir -pv tmp/{dev,proc,sys,run}

b)创建默认节点

mknod -m 600 tmp/dev/console c 5 1

mknod -m 666 tmp/dev/null c 1 3

c)创建初始化文件

mkdir -pv tmp/etc/init.d

cat > tmp/etc/init.d/rcS << EOF

#this is simple start script!!!

echo "mount add part " > /dev/console

mount -t proc /proc

mount -t sysfs /sys

mount -t tmpfs /run

umask 002

echo "this is first exe script" > /dev/console

export PATH=/bin:/sbin/:/usr/bin:/usr/sbin

EOF

chmod a+x tmp/etc/init.d/rcS

cat > tmp/etc/fstab << EOF

#dev  mount-point  type     options           dump fsck-order

/dev/sda1 /        ext3     defaults            1 1

proc /proc    proc     nosuid,noexec,nodev 0 0

sysfs     /sys     sysfs    nosuid,noexec,nodev 0 0

tmpfs     /run     tmpfs    defaults            1 1

devpts    /dev/pts devpts   gid=5,mode=620      0 0

devtmpfs  /dev     devtmpfs mode=0755,nosuid    0 0

EOF

d)拷贝busybox依赖的库

因为busybox依赖于ld-linux.so/libc.so/libm.so等库这些库在编译glibc时编译出来了;拷贝它们到lib中。

使用自动创建脚本:

./create-simple-root.sh busybox-1.23.2/yiyeout/ i486-yiye-linux-

5.使用qemu进行调试linux内核

a)第一步使用qemu加载内核

qemu-system-i386 -S -s -kernel linux-4.0.2/arch/x86/boot/bzImage -hdb basic.img -append "root=/dev/sda1 console=ttyS0" -nographic

-S -s启动gdb同时将程序挂起。

-hdb basic.img将基本根分区,加载为hdb

-kernel linux-4.0.2/arch/x86/boot/bzImage -append "root=/dev/sda1 console=ttyS0"加载内核与内核参数。

-nographic 不是用图形界面,保证得到完整的打印信息。

b)启动新终端,使用gdb调试内核:

gdb linux-4.0.2/vmlinux

设置断点:

b start_kernel

执行之后:

(gdb) b start_kernel

Breakpoint 1 at 0xc19ca77c: file init/main.c, line 490.

链接到qemu的模拟远程环境:

target remote localhost:1234

执行之后

(gdb) target remote localhost:1234

Remote debugging using localhost:1234

继续运行调试内核:

c

之后程序会被停在设置的断点,linux-c代码开始的地方。

(gdb) c

Continuing.

Breakpoint 1, start_kernel () at init/main.c:490

后续就是使用gdb的相关命令进行内核单步调试或者程序跟踪了。

一叶说:根据如上的步骤已经创建好了一个基本的实验环境,而且能够调试内核了。这样来说,对于系统的理解,就可以很直观的运行与追踪了。在如上的过程中,由两个脚本起到了很重要的作用,其实,这是一种有效的学习与总结方式,将好的思想与方法用代码的方式总结,这样不仅能加深思考,同时也方便使用,提高效率。




磨刀不误砍柴工——实验工具准备相关推荐

  1. 磨刀不误砍柴工——数据准备的过程与实践

      众所周知,我们常用"磨刀不误砍柴工"来比喻要办成一件事,不一定要立即着手干活,而是先要进行一些筹划和安排,充分做好准备工作,创造出有利条件,这样不但不会浪费时间,反而会大大提高 ...

  2. linux 测试端口连通性_磨刀不误砍柴工,带你搞定云网络系统性能测试

    磨刀不误砍柴工,带你搞定云网络系统性能测试 一.前言 在部署或管理网络系统时,我们更多的是关心网络的连通性,而对于其整体的性能往往考虑不多,或者即使考虑到性能.异常或稳定性的问题,但却发现没有合适的手 ...

  3. [浪风分享]很简单的查看电脑所支持的最大内存的方法--磨刀不误砍柴工

    硬件+操作系统====决定支持的最大内存 在开始---运行处输入cmd(或者按住winkdy+R键输入CMD),打开命令窗口,输入wmic memphysical get maxcapacity然后回 ...

  4. 磨刀不误砍柴工-----为提升自己找到一个平衡点

    作为一名软件开发人员,你该如何磨快你的锯子? "磨锯子"实际上是一个代名词,泛指一切编程以外的活动(不必编写代码),而这些活动(理论上来说)能使你成为一名更出色的程序员.这个词源自 ...

  5. 制作短视频需注意的三个要点,做好计划再制作,磨刀不误砍柴工

    制作短视频需注意的三个要点,做好计划再制作,磨刀不误砍柴工 俗话说得好,磨刀不误砍柴工,做短视频也是如此.我们在制作短视频之前,还应当注意到三个要点,并做好准备,只有提前做好了制作短视频的准备,我们才 ...

  6. 磨刀不误砍柴工 —— 自己动手写操作系统 入门导引

    磨刀不误砍柴工 刺猬@http://blog.csdn.net/littlehedgehog <自己动手写操作系统>其实阅读所需要的前提不过只是C和汇编了,里面涉及到很多操作系统的东西.于 ...

  7. 磨刀不误砍柴工 ——《自己动手写操作系统》入门导引

    磨刀不误砍柴工 刺猬@http://blog.csdn.net/littlehedgehog <自己动手写操作系统>其实阅读所需要的前提不过只是C和汇编了,里面涉及到很多操作系统的东西.于 ...

  8. 磨刀不误砍柴工:优化你的工具AutoCAD2016,让运行速度更流畅

    高版本的AutoCAD对电脑配置要求越来越高,下面我以AutoCAD2016为例来讲解怎么给自己的CAD加速,使启动运行更快,运行更流畅. 1.启动硬件加速,默认是开启的,高版本AutoCAD右下角有 ...

  9. 磨刀不误砍柴工—— 有用的文件整理、桌面切换工具

    最近做项目,或者说程序员的机子基本上是不关闭的,各种文件和工程需要打开,有时候自己也找了半天才找得到,无奈,我只好寻找一些好的工具,希望可以有助于开发,资源我已经上传. 上传路径:https://do ...

  10. 磨刀不误砍柴工,ORAchk健康检查好帮手

    ORAchk 之前被称为RACcheck,后来它的检查范围进行了扩展,改名为了ORAchk,它是在数据库系统进行健康检查的一个专用工具,这个工具主要用来检查软件的配置是否符合要求以及一些最佳实践是否被 ...

最新文章

  1. OpenGL之gluPerspective浅析
  2. urlrewrite 保持 posturl
  3. 纯java应用搭建,16、BoneCp纯java项目使用
  4. jQuery高度及位置操作
  5. 深夜,在这个已不再喧嚣的城市中寻找到一片属于自己的宁静,仰望那片属于自己的星空……...
  6. 简洁优雅抖音在线qu水印HTML源码
  7. Scrapy爬取美女图片续集 (原创)
  8. 偷窥桌面程序和IE浏览器的密码编辑框
  9. 中国大学MOOC伦理学试题题库及答案
  10. QTP(Quick Test Professional)安装详细教程
  11. 【KEIL-MDK】系列——如何使用PC-Lint代码检查工具
  12. VMware Horizon View许可证如何工作?
  13. 【图神经网络】蛋白质设计proteinsolver跑源码记录
  14. OFDM信号的产生与解调
  15. URI、URL、URN介绍
  16. Dart_Flutter【插件介绍+平台发布+视频】【180个网址导航】
  17. java如何将mp4写入光盘_iOS - 读取/写入mp4视频的XMP元数据
  18. 关于储备(应急储备、管理储备、储备分析)的总结讨论
  19. Python Pyside2 Pinger新手QQ音乐网易云酷狗爬虫下载
  20. 美语音标、节奏与语调以及发音技巧

热门文章

  1. mysql查询前100个_mysql查询前100条数据
  2. 怎么取消计算机文件共享,Win10系统怎么取消文件共享
  3. linux 2.6.32文件系统的dentry父子关系
  4. 2022年最新手机处理器性能排行榜,手机处理器天梯图
  5. css svg做动图,如何制作svg动态图
  6. 方维带货直播最新教程原创文档-申请腾讯云密钥
  7. 【深度学习】3:BP神经网络与MNIST数据集实现手写数字识别
  8. 数字游戏(数位dp)
  9. 实数,有理数,无理数,自然数,整数的概念分别是什么?
  10. 7-5 有理数比较 (10 分)