⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rominit.s

📁 WRS官方的基于VxWorks的X86 BSP通用模版
💻 S
字号:
/* romInit.s - templateX86 ROM initialization module *//* Copyright 1984-1997 Wind River Systems, Inc. */	.data	.globl	_copyright_wind_river	.long	_copyright_wind_river/*modification history--------------------TODO -	Remove the template modification history and begin a new history	starting with version 01a and growing the history upward with	each revision.01b,27aug97,dat  code review comments, added X86 reset notes.01a,27jan97,dat  written (from pc386/romInit.s, ver 01l).*//*TODO - Update documentation as necessary.DESCRIPTIONThis module contains the entry code for VxWorks images that startrunning from ROM, such as 'bootrom' and 'vxWorks_rom'.The entry point, romInit(), is the first code executed on power-up.It performs the minimal setup needed to callthe generic C routine romStart() with parameter BOOT_COLD.RomInit() typically masks interrupts in the processor, sets the initialstack pointer (to STACK_ADRS which is defined in configAll.h), andreadies system memory by configuring the DRAM controller if necessary.Other hardware and device initialization is performed later in theBSP's sysHwInit() routine.A second entry point in romInit.s is called romInitWarm(). It is calledby sysToMonitor() in sysLib.c to perform a warm boot.The warm-start entry point must be written to allow a parameter onthe stack to be passed to romStart().  For X86 processors this is notused. The processor is forced to restart by calling the routine sysReboot().WARNING:This code must be Position Independent Code (PIC).  This means that itshould not contain any absolute address references.  If an absolute addressmust be used, it must be relocated by the macro ROM_ADRS(x).  This macrowill convert the absolute reference to the appropriate address withinROM space no matter how the boot code was linked.  ROM_ADRS() is equivalentto subtracting _romInit and adding ROM_TEXT_ADRS.This code should not call out to subroutines declared in other modules,specifically sysLib.o, and sysALib.o.  If an outside module is absolutelynecessary, it can be linked into the system by adding the module to the makefile variable BOOT_EXTRA.  If the same module is referenced byother BSP code, then that module must be added to MACH_EXTRA as well.Note that some C compilers can generate code with absolute addresses.Such code should not be called from this module.  If absolute addressescannot be avoided, then only ROM resident code can be generated from thismodule.  Compressed and uncompressed bootroms or VxWorks images will notwork if absolute addresses are not processed by the macro ROM_ADRS.WARNING:The most common mistake in BSP development is to attempt to do too muchin romInit.s.  This is not the main hardware initialization routine.Only do enough device initialization to get memory functioning.  All otherdevice setup should be done in sysLib.c, as part of sysHwInit().Unlike other RTOS systems, VxWorks does not use a single linear deviceinitialization phase.  It is common for inexperienced BSP writers to takea BSP from another RTOS, extract the assembly language hardware setupcode and try to paste it into this file.  Because VxWorks provides 3different memory configurations, compressed, uncompressed, and rom-resident,this strategy will usually not work successfully.WARNING:The second most common mistake made by BSP writers is to assume thathardware or CPU setup functions done by romInit.o do not need to berepeated in sysALib.s or sysLib.c.  A vxWorks image needs only the followingfrom a boot program: The startType code, and the boot parameters stringin memory.  Each VxWorks image will completely reset the CPU and allhardware upon startup.  The image should not rely on the boot program toinitialize any part of the system (it may assume that the memory controlleris initialized).This means that all initialization done by romInit.s must be repeated ineither sysALib.s or sysLib.c.  The only exception here could be thememory controller.  However, in most cases even that can bereinitialized without harm.Failure to follow this rule may require users to rebuild bootrom's forminor changes in configuration.  It is WRS policy that bootroms and vxWorksimages should not be linked in this manner.X86 CPU RESET NOTES:The 80x86 will cold boot in REAL (i8086 compatible) mode. In this mode, the 80486 controls 20 address lines, A19-A0 (1MB).  The 80486 CS:EIP pair contains f000:0000fff000 upon initialization.  This is the linear address of 0xffff0.  Upon reset, the processors instruction pointer points to the last 16 bytes of 1MB.  However, upon reset, the 80486 processor actually holds the physical address lines, A31 through A20, at a high level until an intersegment jump instruction is executed. This is because the base address of the code segment in the segment descriptor cache register after processor reset is 0xffff0000) Holding A31-A20 high effectively logical OR's 0xfff00000 to everything applied to the local bus until an intersegment jump occurs.This means that the reset vector of the processor is the physical (bus) address of 0xfffffff0.  The processor, after reset, will therefore be using addresses within the uppermost 64KB of the 32bit (4GB) address space, from 0xffff0000 to 0xffffffff, until the intersegment jumpis used. Another point to note is that since the physical reset vector is 0xfffffff0, the last 16 bytes of physical address space, the very first instruction needs to be a (short) jump back to somewhere above 0xffff0000.So, one needs a bootrom which will jump from the reset vector(0xfffffff0) to somewhere in the uppermost 64KB (above 0xffff0000), then make an intersegment jump. Refer to /target/unsupported/config/frc386 for an example of howto build a bootrom that does this.  The real solution to theproblem lies in a new object module format other than a.out forthe X86 architecture.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "sysLib.h"#include "asm.h"#include "config.h"/* Convert absolute address to ROM equivalent */#define ROM_ADRS(x) 	(x - _romInit + ROM_TEXT_ADRS)	/* internals */	.globl	_romInit	/* start of system code */	.globl	_sdata		/* start of data */_sdata:	.asciz	"start of data"	.text	.align 4/********************************************************************************* romInit - entry point for VxWorks in ROM** romInit (startType)*     int startType;	/@ only used by 2nd entry point @/*/	/*	 * NOTE: The code at 0xfffffff0 does a jump to here (_romInit)	 *	 * This is 16bit REAL mode code, it MUST be in the same	 * 64KB as the reset code (i.e. a 'near' jump).	 */_romInit:	/* following instructions are executed in 16 bit mode */	cli				/* LOCK INTERRUPT */	jmp	cold	.align 4,0x90_romWarmHigh:	cli				/* LOCK INTERRUPT */	movl    SP_ARG1(%esp),%ebx	/* %ebx has the startType */	jmp	warm	.align 4,0x90_romWarmLow:	cli				/* LOCK INTERRUPT */	cld				/* copy itself to the entry point */	movl	$ RAM_LOW_ADRS,%esi	movl	$ ROM_TEXT_ADRS,%edi	movl	$ ROM_SIZE,%ecx	shrl	$2,%ecx	rep	movsl	movl    SP_ARG1(%esp),%ebx	/* %ebx has the startType */	jmp	warm	/* copyright notice appears at beginning of ROM (in TEXT segment) */	.ascii   "Copyright 1984-1997 Wind River Systems, Inc."	.align 4	/* load temporary IDT */cold:	aword			/* next instruction has 32bit address */	word			/* next instruction has 32bit operand */	lidt	%cs:ROM_IDTR	/* load temporary GDT */	aword			/* next instruction has 32bit address */	word			/* next instruction has 32bit operand */	lgdt	%cs:ROM_GDTR	/* switch to protected mode */	mov	%cr0,%eax	/* move CR0 to EAX */	.byte	0x66		/* next instruction has 32bit operand */	or	$0x00000001,%eax/* set the PE bit */	mov	%eax,%cr0	/* move EAX to CR0 */	jmp	romInit1	/* near jump to flush a instruction queue */romInit1:	.byte	0x66		/* next instruction has 32bit operand */	mov	$0x0010,%eax	/* a selector 0x10 is 3rd descriptor */	mov	%ax,%ds		/* load it to DS */	mov	%ax,%es		/* load it to ES */	mov	%ax,%fs		/* load it to FS */	mov	%ax,%gs		/* load it to GS */	mov	%ax,%ss		/* load it to SS */	.byte	0x66		/* next instruction has 32bit operand */	mov	$ ROM_STACK,%esp /* set a stack pointer */	aword			/* next instruction has 32bit address */	word			/* next instruction has 32bit operand */	/*	 * NOTE: This jump must be an inter-segment (i.e. 'far' jump)	 * In order to trigger the release of the A31-A20 address lines.	 */	ljmp	$0x08, $ ROM_TEXT_ADRS + ROM_INIT2 /* far inter segment jump */_romIdtr:	.word	0x0000			/* size   : 0 */	.long	0x00000000		/* address: 0 */_romGdtr:	.word	0x0027			/* size   : 39(8 * 5 - 1) bytes */	.long	ROM_TEXT_ADRS + ROM_GDT /* address: romGdt */	.align 4,0x90_romGdt:	/* 0(selector=0x0000): Null descriptor */	.word	0x0000	.word	0x0000	.byte	0x00	.byte	0x00	.byte	0x00	.byte	0x00	/* 1(selector=0x0008): Code descriptor */	.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 */	/* 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			/* base : 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 : 00xxxxxx */	/* 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 */	/* following instructions are executed in 32 bit mode */	.align 4,0x90_romInit2:	cli				/* LOCK INTERRUPT */	mov	$ ROM_STACK,%esp	/* set a stack pointer */	call	_romA20on		/* enable A20 */	movl    $ BOOT_COLD,%ebx	/* %ebx has the startType */warm:	movl	$_romGdtr,%eax		/* load the original GDT */	subl	$_romInit,%eax	addl	$ ROM_TEXT_ADRS,%eax	pushl	%eax		call	_romLoadGdt	movl	$ STACK_ADRS,%esp	/* initialise the stack pointer */	movl	$0,%ebp			/* initialise the frame pointer */	pushl	$0			/* initialise the %eflags */	popfl	pushl	%ebx			/* push the startType */	cld                             /* copy itself to the entry point */	movl    $ ROM_TEXT_ADRS,%esi	movl    $_romInit,%edi	movl    $_end,%ecx	subl    %edi,%ecx	shrl    $2,%ecx	rep	movsl	movl	$_romStart,%eax		/* jump to romStart */	call	*%eax	/* just in case, if there's a problem in usrInit */_romInitHlt:	hlt		/********************************************************************************* romA20on - enable A20** enable A20** RETURNS: N/A* void romA20on (void) */	.align 4,0x90_romA20on:	/* TODO - if your board needs A20 turned on, do it here */	ret        .align 4,0x90_romA20Result:	.long	0x00000000	/* 0 if A20 is on, -1 if not *//********************************************************************************* romLoadGdt - load the global descriptor table.** RETURNS: N/A** NOMANUAL* void romLoadGdt (char *romGdtr) */        .align 4,0x90_romLoadGdt:	movl	4(%esp),%eax	lgdt	(%eax)	movw	$0x0010,%ax		/* a selector 0x10 is 3rd one */	movw	%ax,%ds		movw	%ax,%es	movw	%ax,%fs	movw	%ax,%gs	movw	%ax,%ss	ret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -