1、VX启动代码romInits文件注释/* romInit.s - PC-386 ROM initialization module */* Copyright 1984-2002 Wind River Systems, Inc. */*modification history-01t,12nov02,hdn made CR4 initialization only for P5 or later (spr 83992)01s,19jun02,hdn updated the copyright year01r,22may02,hdn saved/restored value at 0x0 and
2、 0x10000001q,03apr02,hdn added MP_N_CPU increment with bus locked01p,26mar02,pai Legacy ROM-resident builds require a symbol named _sdata (SPR 74537).01o,19nov01,hdn added WINDML support01n,30aug01,hdn added FUNC/FUNC_LABEL GTEXT/GDATA macro. removed ROM_XXX macro(spr 69891). added romEaxShow.01m,03
3、may00,ms do not call romA20on if booted though SFL.01l,03sep96,hdn added the compression support.01k,21oct94,hdn cleaned up.01j,23sep94,hdn deleted _sysBootType and uses stack.01i,06apr94,hdn moved a processor checking routine to sysALib.s. created the system GDT at GDT_BASE_OFFSET.01h,17feb94,hdn d
4、eleted a piece of code which copy itself to upper memory.01g,27oct93,hdn added _sysBootType.01f,25aug93,hdn changed a way to enable A20.01e,12aug93,hdn added codes to load a user defined global descriptor table.01d,09aug93,hdn added codes to recognize a type of cpu.01c,17jun93,hdn updated to 5.1.01b
5、,26mar93,hdn added some codes to switch to the protected mode01a,19mar92,hdn written by modifying v01c of h32/romInit.s*/*DESCRIPTIONThis module contains the entry code for the VxWorks bootrom.The routine sysToMonitor(2) jumps to the location XXX bytespassed the beginning of romInit, to perform a wa
6、rm boot.This code is intended to be generic accross i80x86 boards.Hardware that requires special register setting or memorymapping to be done immediately, may do so here.*/#define _ASMLANGUAGE / 定义_ASMLANGUAGE。GNU汇编器GAS看到这个定义后,会按照C的语法进行预处理,所以GAS预处理器能够认识C头文件中定义的类型和宏。如果不定义_ASMLANGUAGE,以下的#include语句将无法
7、编译。#include vxWorks.h /系统头文件#include sysLib.h /系统提供给BSP的头文件#include asm.h /汇编头#include config.h /BSP的头文件 .data / 定义数据段 .globl FUNC(copyright_wind_river) / 申明全局变量_copyright_wind_river并使用它定义一个新变量 .long FUNC(copyright_wind_river) /定义一个32-bit的全局变量,变量的初始值为_copyright_wind_river的地址。由于在Makefile中规定了romInit.o
8、为第一个链接的模块,所以这个无名变量将出现在数据段的最开始(没有变量名) /* internals */ .globl romInit /* start of system code */ .globl _romInit /* start of system code */ .globl GTEXT(romWait) /* wait routine */ .globl GTEXT(romA20on) /* turn on A20 */ .globl sdata /* start of data */ .globl _sdata /* start of data */ sdata:_sdata:
9、 .asciz start of data /定义一个以0结尾的字符串”start of data”。这个串出现在数据段的第一个无名变量之后。 .text /程序入口 .balign 16 / .balign是意思是:以当前地址为开始开始,找到第一次出现的以第一个参数为整数倍的地址,并将其作为结束地址,在这个结束地址前面存储一个字节长度的数据,存储内容正是第二个参数。如果当前地址正好是第一个参数的倍数,则没有数据被写入到内存/* romInit - entry point for VxWorks in ROM* romInit (startType)* int startType; / onl
10、y used by 2nd entry point /*/ /* cold start entry point in REAL MODE(16 bits) */romInit: /romInit()函数,其功能是对CPU进行初始化_romInit: / 同时定义_romInit和romInit的原因是,有些编译器产生的对外部符号的调用不加下划线,而有些加。 cli /* LOCK INTERRUPT 关中断*/ jmp cold /* offset must be less than 128 跳转到cold 偏移量必须小于128 跳转指令完成了切换为保护模式 32位指令代码转换*/ /* wa
11、rm start entry point in PROTECTED MODE(32 bits) 在保护模式下热启动入口点(32位)*/ .balign 16,0x90romWarmHigh: /* ROM_WARM_HIGH(0x10) is offset */ cli /* LOCK INTERRUPT 关中断*/ movl SP_ARG1(%esp),%ebx /* %ebx has the startType 把esp+SP_ARG1的值给ebx */ jmp warm /段内相对跳转到warm /* warm start entry point in PROTECTED MODE(32
12、 bits) */ .balign 16,0x90romWarmLow: /* ROM_WARM_LOW(0x20) is offset */ cli /* LOCK INTERRUPT 关中断*/ cld /* copy itself to ROM_TEXT_ADRS 清除方向标志*/ movl $ RAM_LOW_ADRS,%esi /* get src addr (RAM_LOW_ADRS) 赋值给esi*/ movl $ ROM_TEXT_ADRS,%edi /* get dst addr (ROM_TEXT_ADRS) 赋值给edi*/ movl $ ROM_SIZE,%ecx /*
13、 get nBytes to copy 赋值给ecx*/ shrl $2,%ecx /* get nLongs to copy 右移2位*/ rep /* repeat next inst ECX time */ movsl /* copy nLongs from src to dst循环执行esi-edi至dei=0 */ movl SP_ARG1(%esp),%ebx /* %ebx has the startType 把esp+SP_ARG1的值给ebx*/ jmp warm /* jump to warm 跳转到warm*/ /* copyright notice appears at
14、 beginning of ROM (in TEXT segment) */ .ascii Copyright 1984-2002 Wind River Systems, Inc. /* cold start code in REAL MODE(16 bits) */ .balign 16,0x90cold: .byte 0x67, 0x66 /* next inst has 32bit operand 0X66用于反转默认的操作数大小! 0X67用于反转默认的寻址方式*/ lidt %cs:(romIdtr - romInit) /* load temporary IDT 加载(romIdt
15、r - romInit)*/ .byte 0x67, 0x66 /* next inst has 32bit operand */ lgdt %cs:(romGdtr - romInit) /* load temporary GDT 加载(romGdtr - romInit) */ /* switch to protected mode 切换到保护模式*/ mov %cr0,%eax /* move CR0 to EAX CR0中含有控制处理器操作模式和状态的系统控制标志 */ .byte 0x66 /* next inst has 32bit operand */ or $0x0000000
16、1,%eax /* set the PE bit */ mov %eax,%cr0 /* move EAX to CR0 */ jmp romInit1 /* near jump to flush a inst queue 跳转到romInit1*/romInit1: .byte 0x66 /* next inst has 32bit operand */ mov $0x0010,%eax /* set data segment 0x10 is 3rd one */ mov %ax,%ds /* set DS */ mov %ax,%es /* set ES */ mov %ax,%fs /*
17、 set FS */ mov %ax,%gs /* set GS */ mov %ax,%ss /* set SS */ .byte 0x66 /* next inst has 32bit operand */ mov $ ROM_STACK,%esp /* set lower mem stack pointer */*现在已进入保护模式。然而各个段寄存器的值,以及它们的高速缓存寄存器中的值还是老的。把DS, ES, FS, GS, SS寄存器 *设为0x0010,即指向GDT的第2项(从0开始),DPL=0。它们都指向一个段。把堆栈指针esp设为ROM_STACK。 .byte 0x67,
18、0x66 /* next inst has 32bit operand */ ljmp $0x08, $ ROM_TEXT_ADRS + romInit2 - romInit /执行一个远程段间跳转修改CS。CS的新值为0x08,即GDT的第1项,DPL=0。修改CS时它的高速缓存寄存器也会自动更新。以下将进入到32-bit代码模式。 /* temporary IDTR stored in code segment in ROM */romIdtr: .word 0x0000 /* size : 0 */ .long 0x00000000 /* address: 0 */ /* tempora
19、ry GDTR stored in code segment in ROM */romGdtr: .word 0x0027 /* size : 39(8 * 5 - 1) bytes */ .long (romGdt - romInit + ROM_TEXT_ADRS) /* address: romGdt */ /* temporary GDT stored in code segment in ROM */ .balign 16,0x90romGdt: /段描述表 /* 0(selector=0x0000): Null descriptor */ .word 0x0000 .word 0x
20、0000 .byte 0x00 .byte 0x00 .byte 0x00 .byte 0x00 /* 1(selector=0x0008): Code descriptor */ .word 0xffff /* limit: xffff 段接线低16位 */ .word 0x0000 /* base : xxxx0000 基地址低16位*/ .byte 0x00 /* base : xx00xxxx 基地址中间8位*/ .byte 0x9a /* Code e/r, Present, DPL0 段属性*/ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit
21、 段属性含段地址高4位*/ .byte 0x00 /* base : 00xxxxxx 基地址搞8位*/ /* 2(selector=0x0010): Data descriptor */ .word 0xffff /* limit: xffff */ .word 0x0000 /* base : xxxx0000 */ .byte 0x00 /* base : xx00xxxx */ .byte 0x92 /* Data r/w, Present, DPL0 */ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit */ .byte 0x00 /* bas
22、e : 00xxxxxx */ /* 3(selector=0x0018): Code descriptor, for the nesting interrupt */ .word 0xffff /* limit: xffff */ .word 0x0000 /* base : xxxx0000 */ .byte 0x00 /* base : xx00xxxx */ .byte 0x9a /* Code e/r, Present, DPL0 */ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit */ .byte 0x00 /* base : 00xxxx
23、xx */ /* 4(selector=0x0020): Code descriptor, for the nesting interrupt */ .word 0xffff /* limit: xffff */ .word 0x0000 /* base : xxxx0000 */ .byte 0x00 /* base : xx00xxxx */ .byte 0x9a /* Code e/r, Present, DPL0 */ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit */ .byte 0x00 /* base : 00xxxxxx */ /* c
24、old start code in PROTECTED MODE(32 bits) */ .balign 16,0x90romInit2: cli /* LOCK INTERRUPT 关中断*/ movl $ ROM_STACK,%esp /* set a stack pointer 设置esp */#if defined (TGT_CPU) & defined (SYMMETRIC_IO_MODE) movl $ MP_N_CPU, %eax lock incl (%eax)#endif /* defined (TGT_CPU) & defined (SYMMETRIC_IO_MODE) *
25、/ /* WindML + VesaBIOS initialization */ #ifdef INCLUDE_WINDML movl $ VESA_BIOS_DATA_PREFIX,%ebx /* move BIOS prefix addr to EBX */ movl $ VESA_BIOS_KEY_1,(%ebx) /* store BIOS */ addl $4,%ebx /* increment EBX */ movl $ VESA_BIOS_KEY_2,(%ebx) /* store DATA */ movl $ VESA_BIOS_DATA_SIZE,%ecx /* load E
26、CX with nBytes to copy */ shrl $2,%ecx /* get nLongs to copy */ movl $0,%esi /* load ESI with source addr */ movl $ VESA_BIOS_DATA_ADDRESS,%edi /* load EDI with dest addr */ rep movsl /* copy BIOS data to VRAM */#endif /* INCLUDE_WINDML */ /定义INCLUDE_WINDML,并初始化VesaBIOS /* * Dont call romA20on if bo
27、oted through SFL. romA20on does ISA * I/O port accesses to turn A20 on. In case of SFL boot, ISA * I/O address space will not be initialized by properly by the * time this code gets executed. Also, A20 comes ON when booted * through SFL. */#ifndef INCLUDE_IACSFL call FUNC(romA20on) /* enable A20 */
28、cmpl $0, %eax /* is A20 enabled? */ jne romInitHlt /* no: jump romInitHlt */#endif /* INCLUDE_IACSFL */ movl $ BOOT_COLD,%ebx /* %ebx has the startType */ /* copy bootrom image to dst addr if (romInit != ROM_TEXT_ADRS) */warm: ARCH_REGS_INIT /* initialize DR0-7 CR0 EFLAGS 初始化DR标志位寄存器*/#if (CPU = PEN
29、TIUM) | (CPU = PENTIUM2) | (CPU = PENTIUM3) | (CPU = PENTIUM4) /* ARCH_CR4_INIT / initialize CR4 for P5,6,7 */ xorl %eax, %eax /* zero EAX */ movl %eax, %cr4 /* initialize CR4 */#endif /* (CPU = PENTIUM) | (CPU = PENTIUM234) 如果是奔腾系列初清零CR4*/ movl $romGdtr,%eax /* load the original GDT 加载前面段描述表romGdtr
30、*/ subl $ FUNC(romInit),%eax addl $ ROM_TEXT_ADRS,%eax pushl %eax call FUNC(romLoadGdt) movl $ STACK_ADRS, %esp /* initialise the stack pointer */ movl $ ROM_TEXT_ADRS, %esi /* get src addr(ROM_TEXT_ADRS) */ movl $ romInit, %edi /* get dst addr(romInit) */ cmpl %esi, %edi /* is src and dst same? */ je romInit4 /* yes: skip copying 比较ROM_TEXT_ADRS和romInit相同则跳转romInit4*/ movl $ FUNC(end), %ecx /* get end addr */ subl %edi, %ecx /* get nBytes to copy */ shrl $2, %ecx /* get nLongs to copy */ cld /* clear the direction
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1