coreboot学习3:启动流程跟踪之bootblock阶段
2016-03-14 21:53
501 查看
coreboot的第一个启动阶段为bootblock。该阶段均使用汇编语言编写。下面根据执行文件顺序介绍。
下面语句定义其为16位代码段。
1、关中断:
主要是设置cr0寄存器,其中PE为1表示保护模式。
1、GDT表相关定义
GDT表中有三个表项:
第一个是GDT表项的基地址和大小作为limit。
第二个是基地址为0x00000000段界限为4GB的代码段。
第三个是与第二个相同地址的数据段。
以上是简单的代码注释。其中BIST贯穿着整个阶段,它是romstage入口函数的参数。BIST为英文“Built-In Self-Test”简称,在CPU上电或复位后,如果eax的值为0,则表示测试通过,参考intel软件开发人员文档3A 9.1.2。关于GDT表相关知识,可以参阅于渊编写的《Orange'S:一个操作系统的实现》。
另外:
在代码分析时,使用临时值赋给eax寄存器,作为跟踪的一个手段。
对于coreboot代码编译生成还未十分掌握、理解。
本文未对跳转到下一阶段romstage做分析。
注:
由于coreboot方面资料较少,笔者第一次尝试分析代码,还有众多未能参透的地方,难免出错。任何问题,欢迎一起交流学习。
http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
coreboot仓库:https://github.com/coreboot/coreboot
http://blog.csdn.net/shuanghuo9/article/details/6574261
Orange'S:一个操作系统的实现:https://book.douban.com/subject/3735649/
李迟 2016.3.14 周一 晚
一、reset16.inc
bootlbock的最开始执行的文件为src\cpu\x86\16bit\reset16.inc。该文件十分简单,如下:.section ".reset", "ax", %progbits .code16 .globl _start _start: .byte 0xe9 .int _start16bit - ( . + 2 ) /* Note: The above jump is hand coded to work around bugs in binutils. * 5 byte are used for a 3 byte instruction. This works because x86 * is little endian and allows us to use supported 32bit relocations * instead of the weird 16 bit relocations that binutils does not * handle consistenly between versions because they are used so rarely. */ .previous里面的_start16bit在entry16.inc中定义。
二、 entry16.inc
从文件src\cpu\x86\16bit\ entry16.inc名称上看出,该文件为16位的汇编代码,主要做一些初始工作,接着便进入到保护模式。下面语句定义其为16位代码段。
.code16 .globl _start16bit .type _start16bit, @function
1、关中断:
_start16bit: /* 关中断 */ cli2、保存BIST的值
/* Save the BIST result */ /* 保存eax的BIST(Built-In Self-Test)的值,上电或复位后,eax值为0表示所有的测试通过,参见intel开发文档3A 9.1.2 */ movl %eax, %ebp3、将cr3清零
/* cr3清零,使TLB无效(cache无效) — CR3:页目录基址的物理地址和PCD和PWT标志位(和CACHE有关) */ xorl %eax, %eax movl %eax, %cr3 /* Invalidate TLB*/4、
movw %cs, %ax shlw $4, %ax movw $nullidt_offset, %bx subw %ax, %bx lidt %cs:(%bx) movw $gdtptr16_offset, %bx subw %ax, %bx lgdtl %cs:(%bx)5、进入保护模式
主要是设置cr0寄存器,其中PE为1表示保护模式。
/* 进入保护模式 PE为1 */ movl %cr0, %eax andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */ orl $0x60000001, %eax /* CD, NW, PE = 1 */ movl %eax, %cr06、恢复BIST值到eax寄存器
/* 重新赋值BIST到eax */ /* 测试用的 -- movl $0xab, %eax*/ /* Restore BIST to %eax */ movl %ebp, %eax7、跳转到保护模式
/* Now that we are in protected mode jump to a 32 bit code segment. */ ljmpl $ROM_CODE_SEG, $__protected_start之后便到entry32.inc文件。
三、entry32.inc
文件:src\cpu\x86\16bit\ entry32.inc。开始处的.code32定义其为32位代码段。1、GDT表相关定义
GDT表中有三个表项:
第一个是GDT表项的基地址和大小作为limit。
第二个是基地址为0x00000000段界限为4GB的代码段。
第三个是与第二个相同地址的数据段。
/* This is the GDT for the ROM stage part of coreboot. It * is different from the RAM stage GDT which is defined in * c_start.S */ .align 4 .globl gdtptr gdt: gdtptr: .word gdt_end - gdt -1 /* compute the table limit */ .long gdt /* we know the offset */ .word 0 /* selgdt 0x08, flat code segment */ .word 0xffff, 0x0000 .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */ /* selgdt 0x10,flat data segment */ .word 0xffff, 0x0000 .byte 0x00, 0x93, 0xcf, 0x00 /* selgdt 0x18, flat code segment (64-bit) */ .word 0xffff, 0x0000 .byte 0x00, 0x9b, 0xaf, 0x00 gdt_end:2、保存BIST值
lgdt %cs:gdtptr ljmp $ROM_CODE_SEG, $__protected_start __protected_start: /* Save the BIST value */ movl %eax, %ebp3、把除了CS以外的数据段全部加载到第三个GDT表项上。
movw $ROM_DATA_SEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss movw %ax, %fs movw %ax, %gs4、恢复BIST值
/* Restore the BIST value to %eax */ /* 恢复BIST值到eax,以qemu x86为例,在cache as ram阶段,会保存此值,而最后romstage入口函数参数即为BIST */ /* 测试用的 -- movl $0xaa, %eax */ movl %ebp, %eax
以上是简单的代码注释。其中BIST贯穿着整个阶段,它是romstage入口函数的参数。BIST为英文“Built-In Self-Test”简称,在CPU上电或复位后,如果eax的值为0,则表示测试通过,参考intel软件开发人员文档3A 9.1.2。关于GDT表相关知识,可以参阅于渊编写的《Orange'S:一个操作系统的实现》。
另外:
在代码分析时,使用临时值赋给eax寄存器,作为跟踪的一个手段。
对于coreboot代码编译生成还未十分掌握、理解。
本文未对跳转到下一阶段romstage做分析。
注:
由于coreboot方面资料较少,笔者第一次尝试分析代码,还有众多未能参透的地方,难免出错。任何问题,欢迎一起交流学习。
参考资料:
Intel 64 and IA-32 Architectures Software Developer’s Manual手册下载地址:http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
coreboot仓库:https://github.com/coreboot/coreboot
http://blog.csdn.net/shuanghuo9/article/details/6574261
Orange'S:一个操作系统的实现:https://book.douban.com/subject/3735649/
李迟 2016.3.14 周一 晚
相关文章推荐
- iOS 基于MVVM设计模式练习UITableView使用 —— HERO博客
- stm32通过485接串口做IAP
- 电子商务网站测试经验总结
- Java 多线程:Lock 关键字
- jvm虚拟机类加载机制
- Vector和ArrayList的区别
- SAP接口编程-Nco3.0系列01 : RfcDestination
- Problem E: C语言习题 等长字符串排序
- IP协议
- 最大子数组
- 需求获取常见的方法是进行客户访谈,结合你的实践谈谈会遇到什么问题,你是怎么解决的?
- spring控制器
- leetcode 59. Spiral Matrix II
- Problem D: C语言习题 字符串比较
- Ubuntu SCIM输入法的安装
- 监控系统、工具的重要性
- OpenCv实现卷积神经网络实例:tiny_cnn代码详解(6)——average_pooling_layer层结构类分析
- DIV+CSS 网页布局之:一列布局
- Linux 程序启停脚本
- 001 高性能IO模型浅析