第一次写的lab1练习1太冗杂,没有重点,理解不到位,后续进一步研究后感觉务必重新写一篇。。。。。。
[练习1.1] 操作系统镜像文件 ucore.img 是如何一步一步生成的
生成ucore.img的相关代码
在Makefile中:
为了生成ucore.img,首先需要生成bootblock、kernel
一、生成bootblock的相关代码
(一)为了生成bootblock,首先需要生成bootasm.o、bootmain.o、sign
1、生成bootasm.o,bootmain.o的相关makefile代码为
实际代码由宏批量生成
(1、 生成bootasm.o需要bootasm.S,实际命令为
(执行make后的命令)
其中关键的参数为:
-ggdb 生成可供gdb使用的调试信息
-m32 生成适用于32位环境的代码
-gstabs 生成stabs格式的调试信息
-nostdinc 不使用标准库
-fno-stack-protector 不生成用于检测缓冲区溢出的代码
-Os 为减小代码大小而进行优化
-I<dir’>'添加搜索头文件的路径
(2 、生成bootmain.o需要bootmain.c,实际命令为
(执行make后的命令)
新出现的关键参数有:
-fno-builtin 除非用__builtin_前缀,否则不进行builtin函数的优化
(3、生成sign工具的makefile代码为(Makefile源文件中)
实际命令为
(执行make后的命令)
(二)首先生成bootblock.o
(执行make后的命令)
其中关键的参数为:
-m 模拟为i386上的连接器
-nostdlib 不使用标准库
-N 设置代码段和数据段均可读写
-e 指定入口
-Ttext 制定代码段开始位置
(三)拷贝二进制代码bootblock.o到bootblock.out的命令
(执行make后的命令)
其中关键的参数为:
-S 移除所有符号和重定位信息
-O 指定输出格式
使用sign工具处理bootblock.out,生成bootblock的命令
二、生成kernel的相关代码
(一)为了生成kernel,首先需要 kernel.ld init.o readline.o stdio.o kdebug.o
为了生成kernel,首先需要很多相关文件
1、在obj/kern中生成很多.o文件相关makefile代码为
这些.o生成方式和参数均类似,其中对一个说明
(1、 在 kern/trap/trap.c 生成 trap.o
(执行make后的命令)
可以看出用gcc命令(图中为cc,因为文件中前面定义过)把trap.c源文件编译了生成了trap.o文件了
(二)生成kernel时,必需的命令只有
(执行make后的命令)
其中新出现的关键参数为:
-T 让连接器使用指定的脚本
bootblock 和 kernel 写入
生成一个有10000个块的文件,每个块默认512字节,用0填充
(执行make后的命令)
1、把bootblock中的内容写到第一个块
2、从第二个块开始写kernel中的内容
[练习1.2] 一个被系统认为是符合规范的硬盘主引导扇区的特征是什么
在sign.c中看到,一个磁盘主引导扇区只有512字节。且
第510个(倒数第二个)字节是0x55,
第511个(倒数第一个)字节是0xAA。
[练习2] 使用qemu执行并调试lab1中的软件
进行如下的小练习:
- 从CPU加电后执行的第一条指令开始,单步跟踪BIOS的执行。
- 在初始化位置0x7c00设置实地址断点,测试断点正常。
- 从0x7c00开始跟踪代码运行,将单步跟踪反汇编得到的代码与bootasm.S和 bootblock.asm进行比较。
- 自己找一个bootloader或内核中的代码位置,设置断点并进行测试。
一、基本提示
make lab1-mon代码有什么用
先进入lab1_result文件中,在命令行中输入:
less Makefile
再输入:
lab1-mon
这个命令找到程序中lab1-mon这个命令所在位置:
第一个是让qemu把它执行的命令给记录下来,把log信息记录下来
第二个是和GDB结合来调试正在执行的Bootloader
注意这里还没有到uCore,还在Bootloader阶段
看一下GDB调试的 lab1init:
说明:
1:加载kernel
2:与qemu进行连接,通过TRP
3:BIOS进入是8086的16位实模式方式,一直到0X7C00再BIOS这个阶段启动,最后把Bootloader加载进去,将控制权交给Bootloader
4:设置一个断点break 0X7C00,Bootloader的第一条指令在此
5:系统继续运行
6:pc就是eip,也就是指令的指针寄存器,x是显示的意思,/2i表示显示两条指令
看一下执行的效果,输入:
make lab1-mon
开启了两个窗口,qemu已经启动起来了
qemu断了,在 0X7C00 处
这时显示了断点后的两条指令