ucore - LAB1实验报告(2)
seta20.1: inb $0x64, %al # Wait for not busy testb $0x2, %al jnz seta20.1 movb $0xd1, %al # 0xd1 -> port 0x64 outb %al, $0x64
seta20.2: inb $0x64, %al # Wait for not busy testb $0x2, %al jnz seta20.2 movb $0xdf, %al # 0xdf -> port 0x60 outb %al, $0x60 (4) lgdt gdtdesc //重新加载GDT表 movl %cr0, êx orl $CR0_PE_ON, êx //设置CR0寄存器PE位,PE位(第0位)是启用保护(Protection Enable)标志位。该位为0时为实地址模式,设置为1时开启保护模式,开启分页机制 movl êx, %cr0 ljmp $PROT_MODE_CSEG, $protcseg
(5)//进入32位模式,$PROT_MODE_CSEG表示段选择子,被加载到CS寄存器中,$protcseg被加载到IP寄存器中。CS、IP寄存器会重新加载,后面的代码都在32位保护模式下执行。
.code32 # Assemble for 32-bitmode protcseg:
//设置保护模式下的段寄存器
movw $PROT_MODE_DSEG, %ax # Our data segment lector movw %ax, %ds # -> DS: Data Segment movw %ax, %es # -> ES: Extra Segment movw %ax, %fs # -> FS movw %ax, %gs # -> GS
movw %ax, %ss # -> SS: Stack Segment //设置栈指针,程序跳转到0x7c00 movl $0x0, ?p movl $start, %esp
call bootmain
练习4:分析bootloader加载ELF格式的OS 1. bootloader如何读取硬盘扇区的?
答:读一个扇区的流程可参看bootmain.c 中的 readsect 函数实现。大致如下:
1. 读 I/O 地址 0x1f7,等待磁盘准备好;
2. 写 I/O 地址 0x1f2~0x1f5,0x1f7,发出读取第 offseet 个扇区处的磁盘数据的命令; 3. 读 I/O 地址 0x1f7,等待磁盘准备好;
4. 连续读 I/O 地址 0x1f0,把磁盘扇区数据读到指定内存。 /* readsect - read a single sector at @secno into @dst */ static void
readsect(void *dst, uint32_t secno) { // 第1步:等待硬盘准备好 waitdisk();
// 第2步:发出读取扇区的命令 outb(0x1F2, 1); // 读取一个扇区 outb(0x1F3, secno & 0xFF); // LBA参数的0~7位 outb(0x1F4, (secno >> 8) & 0xFF); // LBA参数的8~15位 outb(0x1F5, (secno >> 16) & 0xFF); // LBA参数的16~23位 outb(0x1F6, ((secno >> 24) & 0xF) | 0xE0); // LBA参数的24~27位 outb(0x1F7, 0x20); // 状态和命令寄存器。命令 0x20 - 读取扇区 // 第3步:等待硬盘准备好 waitdisk();
// 第4步:把磁盘扇区数据读取到指定内存 insl(0x1F0, dst, SECTSIZE / 4); }
2. bootloader是如何加载ELF格式的OS?
答:bootmain函数中完成加载ELF格式os的操作:
1: 读取ELF的头部
2: 判断ELF文件是否是合法 3: 将描述表的头地址存在ph
4: 按照描述表将ELF文件中数据载入内存
5: 根据ELF头部储存的入口信息,找到内核的入口(不再返回) 具体在bootmain.c的函数main()中实现: // 读取硬盘的第一页(载入kernel的文件头) readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); // 判断是否为有效的ELF if (ELFHDR->e_magic != ELF_MAGIC) { goto bad; } struct proghdr *ph, *eph; // 从硬盘载入程序片段到内存(忽略ph标志) ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff); eph = ph + ELFHDR->e_phnum;
for (; ph < eph; ph ++) { readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); }
// 从elf->entry为入口进入程序 // 注意:不返回
((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))();
练习5:实现函数调用堆栈跟踪函数 答:void print_stackframe(void{
uint32_t ebp = read_ebp(), eip = read_eip(); int i, j;
for (i = 0; ebp != 0 && i < STACKFRAME_DEPTH; i ++) { cprintf(\ uint32_t *args = (uint32_t *)ebp + 2; for (j = 0; j < 4; j ++) {
cprintf(\ }
cprintf(\
print_debuginfo(eip - 1); eip = ((uint32_t *)ebp)[1]; ebp = ((uint32_t *)ebp)[0]; …… 此处隐藏:475字,全部文档内容请下载后查看。喜欢就下载吧 ……
相关推荐:
- [高等教育]公司协助某村精准扶贫工作总结.doc
- [高等教育]高二生物知识点总结(全)
- [高等教育]苏教版数学三年级下册《解决问题的策略
- [高等教育]仪器分析课程学习心得
- [高等教育]2017年五邑大学数学与计算科学学院333
- [高等教育]人教版七年级下册语文第四单元测试题(
- [高等教育]2018年秋七年级英语上册Unit7Howmuchar
- [高等教育]2017年八年级下数学教学工作小结
- [高等教育]湖南省怀化市2019届高三统一模拟考试(
- [高等教育]四年级下册科学_基础训练及答案教材
- [高等教育]城郊煤矿西风井管路伸缩器更换施工安全
- [高等教育]昆八中20182019学年度上学期期末考试
- [高等教育]项目部各类人员任命书
- [高等教育]上市公司经营水务产业的模式
- [高等教育]人教版高二化学第一学期第三章水溶液中
- [高等教育]【中考物理第一轮复习资料】四.压强与
- [高等教育]金坑水电站报废改建工程机电设备更新改
- [高等教育]高中生物教学工作计划简易版
- [高等教育]2017年西华大学攀枝花学院(联合办学)44
- [高等教育]最新整理超短爆笑英文小笑话大全
- 优秀教师继续教育学习心得体会
- 阳历到阴历的转换
- 留守儿童教育案例分析
- 华师17春秋学期《玩教具制作与环境布置
- 测速传感器新型安装装置的现场应用
- 人教版小学数学三年级下册第四单元
- 创业个人意向书
- 山东省潍坊市2012年高考仿真试题(三)
- [恒心][好卷速递]四川省成都外国语学校
- 多少人错把好转反应当成了病情加重处理
- 中外广播电视史复习资料整理
- 江苏省扬州市江都区宜陵镇中学2014-201
- 工程造价专业毕业实习报告
- 广西师范学院心理与教育统计
- aympkrq基于 - asp的博客网站设计与开
- 建筑业外出经营相关流程操作(营改增后
- 人治 德治 法治
- [精华篇]常识判断专项训练题库
- 中国共产党为什么要实行民主集中
- 小学数学第三册第一单元试卷(A、B、C




