完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
一个bootloader
可以切换到X86保护模式 能够读磁盘并加载ELF执行文件格式 显示字符 一个OS 可以处理时钟中断 显示字符 项目组成 lab1的整体目录结构如下所示: 其中一些比较重要的文件说明如下: bootloader部分 boot/bootasm.S :定义并实现了bootloader最先执行的函数start,此函数进行了一定的初始化,完成了从实模式到保护模式的转换,并调用bootmain.c中的bootmain函数。 boot/bootmain.c:定义并实现了bootmain函数实现了通过屏幕、串口和并口显示字符串。bootmain函数加载ucore操作系统到内存,然后跳转到ucore的入口处执行。 boot/asm.h:是bootasm.S汇编文件所需要的头文件,主要是一些与X86保护模式的段访问方式相关的宏定义。 ucore操作系统部分 系统初始化部分: kern/init/init.c:ucore操作系统的初始化启动代码 内存管理部分: kern/mm/memlayout.h:ucore操作系统有关段管理(段描述符编号、段号等)的一些宏定义 kern/mm/mmu.h:ucore操作系统有关X86 MMU等硬件相关的定义,包括EFLAGS寄存器中各位的含义,应用/系统段类型,中断门描述符定义,段描述符定义,任务状态段定义,NULL段声明的宏SEG_NULL, 特定段声明的宏SEG,设置中 断门描述符的宏SETGATE(在练习6中会用到) kern/mm/pmm.[ch]:设定了ucore操作系统在段机制中要用到的全局变量:任务状态段ts,全局描述符表 gdt[],加载全局描述符表寄存器的函数lgdt,临时的内核栈stack0;以及对全局描述符表和任务状态段的初始化函数gdt_init 外设驱动部分: kern/driver/intr.[ch]:实现了通过设置CPU的eflags来屏蔽和使能中断的函数; kern/driver/picirq.[ch]:实现了对中断控制器8259A的初始化和使能操作; kern/driver/clock.[ch]:实现了对时钟控制器8253的初始化操作;- kern/driver/console. [ch]:实现了对串口和键盘的中断方式的处理操作; 中断处理部分: kern/trap/vectors.S:包括256个中断服务例程的入口地址和第一步初步处理实现。注意,此文件是由tools/vector.c在编译ucore期间动态生成的; kern/trap/trapentry.S:紧接着第一步初步处理后,进一步完成第二步初步处理;并且有恢复中断上下文的处理,即中断处理完毕后的返回准备工作; kern/trap/trap.[ch]:紧接着第二步初步处理后,继续完成具体的各种中断处理操作; 内核调试部分: kern/debug/kdebug.[ch]:提供源码和二进制对应关系的查询功能,用于显示调用栈关系。其中补全print_stackframe函数是需要完成的练习。其他实现部分不必深究。 kern/debug/kmonitor.[ch]:实现提供动态分析命令的kernel monitor,便于在ucore出现bug或问题后,能够进入kernel monitor中,查看当前调用关系。实现部分不必深究。 kern/debug/panic.c | assert.h:提供了panic函数和assert宏,便于在发现错误后,调用kernel monitor。大家可在编程实验中充分利用assert宏和panic函数,提高查找错误的效率。 公共库部分 libs/defs.h:包含一些无符号整型的缩写定义。 Libs/x86.h:一些用GNU C嵌入式汇编实现的C函数(由于使用了inline关键字,所以可以理解为宏)。 工具部分 Makefile和function.mk:指导make完成整个软件项目的编译,清除等工作。 sign.c:一个C语言小程序,是辅助工具,用于生成一个符合规范的硬盘主引导扇区。 tools/vector.c:生成vectors.S,此文件包含了中断向量处理的统一实现。 编译方法 首先下载lab1.tar.bz2,然后解压lab1.tar.bz2。在lab1目录下执行make,可以生成ucore.img(生成于bin目录下)。ucore.img是一个包含了bootloader或OS的硬盘镜像,通过执行如下命令可在硬件虚拟环境 qemu中运行bootloader或OS: $ make qemu 则可以得到如下显示界面*(仅供参考)* 练习1 理解通过make生成执行文件的过程。 问题 操作系统镜像文件ucore.img是如何一步一步生成的?(需要比较详细地解释Makefile中每一条相关命令和命令参数的含义,以及说明命令导致的结果) 一个被系统认为是符合规范的硬盘主引导扇区的特征是什么? 补充材料 如何调试Makefile 当执行make时,一般只会显示输出,不会显示make到底执行了哪些命令。 如想了解make执行了哪些命令,可以执行:(记住,V是大写) $ make “V=” 要获取更多有关make的信息,可上网查询,并请执行 $ man make 实验过程 问题1 操作系统镜像文件ucore.img是如何一步一步生成的?(需要比较详细地解释Makefile中每一条相关命令和命令参数的含义,以及说明命令导致的结果) 首先,进入~/ucore_os_lab-master/labcodes_answer/lab1_result目录下 执行make,并查看详情 $ make “V=” 观察输出结果 (1)通过GCC编译器将Kernel目录下的.c文件编译成OBJ目录下的.o文件。 为了生成ucore.img,首先需要生成bootblock、kernel 为了生成bootblock,首先需要生成bootasm.o、bootmain.o、sign 递归下去 为了生成kernel,首先需要 kernel.ld init.o readline.o stdio.o kdebug.o 递归下去 问题2 一个被系统认为是符合规范的硬盘主引导扇区的特征是什么? 我们可以查看tools下的sign.c文件 从sign.c的代码来看,一个磁盘主引导扇区只有512字节。且第510个(倒数第二个)字节是0x55,第511个(倒数第一个)字节是0xAA。 练习2 使用qemu执行并调试lab1中的软件。 实验要求 从CPU加电后执行的第一条指令开始,单步跟踪BIOS的执行。 在初始化位置0x7c00设置实地址断点,测试断点正常。 从0x7c00开始跟踪代码运行,将单步跟踪反汇编得到的代码与bootasm.S和bootblock.asm进行比较。 自己找一个bootloader或内核中的代码位置,设置断点并进行测试。 提示:参考附录“启动后第一条执行的指令”,可了解更详细的解释,以及如何单步调试和 查看BIOS代码。 提示:查看 labcodes_answer/lab1_result/tools/lab1init 文件,用如下命令试试如何调试 bootloader第一条指令: $ cd labcodes_answer/lab1_result/ $ make lab1-mon 补充材料 我们主要通过硬件模拟器qemu来进行各种实验。在实验的过程中我们可能会遇上各种各样的问题,调试是必要的。qemu支持使用gdb进行的强大而方便的调试。所以用好qemu和gdb是完成各种实验的基本要素。 默认的gdb需要进行一些额外的配置才进行qemu的调试任务。qemu和gdb之间使用网络端口1234进行通讯。在打开qemu进行模拟之后,执行gdb并输入 target remote localhost:1234 即可连接qemu,此时qemu会进入停止状态,听从gdb的命令。 另外,我们可能需要qemu在一开始便进入等待模式,则我们不再使用make qemu开始系统的运行,而使用make debug来完成这项工作。这样qemu便不会在gdb尚未连接的时候擅自运行了。 gdb的地址断点 在gdb命令行中,使用b *[地址]便可以在指定内存地址设置断点,当qemu中的cpu执行到指定地址时,便会将控制权交给gdb。 关于代码的反汇编 有可能gdb无法正确获取当前qemu执行的汇编指令,通过如下配置可以在每次gdb命令行前强制反汇编当前的指令,在gdb命令行或配置文件中添加: define hook-stop x/i $pc end 即可 gdb的单步命令 在gdb中,有next, nexti, step, stepi等指令来单步调试程序,他们功能各不相同,区别在于单步的“跨度”上。 next 单步到程序源代码的下一行,不进入函数。 nexti 单步一条机器指令,不进入函数。 step 单步到下一个不同的源代码行(包括进入函数)。 stepi 单步一条机器指令。 实验过程 问题1 从CPU加电后执行的第一条指令开始,单步跟踪BIOS的执行。 直接看截图吧,就是玩玩gdb那几个命令而已 这是直接拿答案的代码了,拿题目的是这样: (1)进入~/moocos/ucore_lab/labcodes/lab1/bin,即ucore.img所在文件夹。 (2)输入指令: qemu -S -s -hda ucore.img -monitor stdio (3)打开gdb。 (4)输入命令,使gdb与qemu通过1234端口进行通信,qemu会停止状态听从gbd命令。 target remote 127.0.0.1:1234 (5)输入命令,单步跟踪。 si 问题2 在初始化位置0x7c00设置实地址断点,测试断点正常。 (1)输入命令,设置断点。 b *0x7c00 (2)continue后,测试断点。 c x/2i $pc 运行结果: (gdb) target remote 127.0.0.1:1234 Remote debugging using 127.0.0.1:1234 0x0000fff0 in ?? () (gdb) b *0x7c00 Breakpoint 1 at 0x7c00 (gdb) c Continuing. Breakpoint 1, 0x00007c00 in ?? () (gdb) x /2i $pc =》 0x7c00: cli 0x7c01: cld 问题3 从0x7c00开始跟踪代码运行,将单步跟踪反汇编得到的代码与bootasm.S和bootblock.asm进行比较。 使用meld对比bootasm.S和bootlock.asm的代码 meld /home/moocos/moocos/ucore_lab/labcodes/lab1/boot/bootasm.S /home/moocos/moocos/ucore_lab/labcodes/lab1/obj/bootblock.asm 看就完了,是一样的 问题4 自己找一个bootloader或内核中的代码位置,设置断点并进行测试。 (略) 补充 在进入练习3前,再复习一下bootloader做了什么: 切换到保护模式,启用分段机制 (修改A20地址线) 读磁盘中ELF执行文件格式的ucore操作系统到内存 显示字符串信息 把控制权交给ucore操作系统 保护模式下,有两个段表:GDT(Global Descriptor Table)和LDT(Local Descriptor Table),每一张段表可以包含8192 (2^13)个描述符,因而最多可以同时存在2 * 2^13 = 2^14 个段。虽然保护模式下可以有这么多段,逻辑地址空间看起来很大,但实际上段并不能扩展物理地址空间,很大程度上各个段的地址空间是相互重叠的。所谓的64TB(2^(14+32) =246)逻辑地址空间是一个理论值,没有实际意义。在32位保护模式下,真正的物理空间仍然只有232字节那么大。(注:在ucore lab中只用到了GDT,没有用LDT。) 练习3 分析bootloader进入保护模式的过程。 实验要求 BIOS将通过读取硬盘主引导扇区到内存,并转跳到对应内存中的位置执行bootloader。请分析bootloader是如何完成从实模式进入保护模式的。 提示:需要阅读小节**“保护模式和分段机制”**和lab1/boot/bootasm.S源码,了解如何从实模式切换到保护模式,需要了解: 为何开启A20,以及如何开启A20 如何初始化GDT表 如何使能和进入保护模式 实验过程 打开lab1/boot/bootasm.S 清理环境:关中断,重要的段寄存器清零 开启A20(为了与最早的PC兼容,物理地址线绑定在了低20位,因此高于1MB的地址默认情况下会回零。 此代码撤消了此操作),通过将键盘控制器上的A20线置于高电位,全部32条地址线可用,可以访问4G的内存空间。 设备和芯片的I/O端口操作实现,其实没有复杂的东西在里边 ,I/O端口操作主要是看一堆文档,把整个X86架构的PC机所有I/O端口记住,并记住它们每一个数据寄存器、命令寄存器等操作访问标准(也可以称之协议) ; 记住之后,整个过程中就是按标准使用I/O指令。 in, out(只能与DX,AX,AL寄存器结合使用) ; 下面的实现是提供给C使用,语法太晦涩,所以直接使用汇编实现。 inb 从I/O端口读取一个字节(BYTE, HALF-WORD) ; outb 向I/O端口写入一个字节(BYTE, HALF-WORD); inw 从I/O端口读取一个字(WORD,即两个字节); outw 向I/O端口写入一个字(WORD,即两个字节) ; 初始化GDT(全局描述表,Global Descriptor Table),一个简单的GDT表和其描述符已经静态储存在引导区中,载入即可 进入保护模式:通过将cr0寄存器PE位(第0位)置1便开启了保护模式;通过长跳转更新cs的基地址;设置段寄存器,并建立堆栈(BIOS数据区:0x0000-0x7c00) call bootmain 使用引导程序GDT和段转换,使虚拟地址与物理地址相同,从而从实模式切换到保护模式,从而使有效内存映射在切换期间不会改变。 |
|
|
|
只有小组成员才能发言,加入小组>>
4345个成员聚集在这个小组
加入小组3287 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4233 浏览 1 评论
4239 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 06:01 , Processed in 0.860531 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号