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

📄 startmpcc.s

📁 Etherboot 是一个用来创建ROM images的软件包
💻 S
字号:
/* #defines because ljmp wants a number, probably gas bug *//*	.equ	KERN_CODE_SEG,_pmcs-_gdt	*/#define	KERN_CODE_SEG	0x08	.equ	KERN_DATA_SEG,_pmds-_gdt/*	.equ	REAL_CODE_SEG,_rmcs-_gdt	*/#define	REAL_CODE_SEG	0x18	.equ	REAL_DATA_SEG,_rmds-_gdt	.equ	CR0_PE,1#ifdef	GAS291#define DATA32 data32;#define ADDR32 addr32;#define	LJMPI(x)	ljmp	x#else#define DATA32 data32#define ADDR32 addr32/* newer GAS295 require #define	LJMPI(x)	ljmp	*x */#define	LJMPI(x)	ljmp	x#endif#define PIC1_VBS  0x08      /* PIC1 interrupts start at vector 64  */#define PIC2_VBS  0x70      /* PIC1 interrupts start at vector 112  *//* * NOTE: if you write a subroutine that is called from C code (gcc/egcs), * then you only have to take care of %ebx, %esi, %edi and %ebp.  These * registers must not be altered under any circumstance.  All other registers * may be clobbered without any negative side effects.  If you don't follow * this rule then you'll run into strange effects that only occur on some * gcc versions (because the register allocator may use different registers). * * All the data32 prefixes for the ljmp instructions are necessary, because * the assembler emits code with a relocation address of 0.  This means that * all destinations are initially negative, which the assembler doesn't grok, * because for some reason negative numbers don't fit into 16 bits. The addr32 * prefixes are there for the same reasons, because otherwise the memory * references are only 16 bit wide.  Theoretically they are all superfluous. * One last note about prefixes: the data32 prefixes on all call _real_to_prot * instructions could be removed if the _real_to_prot function is changed to * deal correctly with 16 bit return addresses.  I tried it, but failed. *//**************************************************************************START - Where all the fun begins....**************************************************************************//* this must be the first thing in the file because we enter from the top */	.global	_start	.code32_start:	cli		/* load new IDT and GDT */	lgdt	gdtarg	lidt	Idt_Reg	/* flush prefetch queue, and reload %cs:%eip */	ljmp	$KERN_CODE_SEG,$1f1:		/* reload other segment registers */	movl	$KERN_DATA_SEG,%eax	movl	%eax,%ds	movl	%eax,%es	movl	%eax,%ss        movl    $stktop,%esp	/* program the PITs in order to stop them */        mov	$0x30,%al	out	%al,$0x43	out	%al,$0x40        mov	$0x70,%al	out	%al,$0x43	out	%al,$0x41        mov	$0xf0,%al	out	%al,$0x43	out	%al,$0x42		call	main	/* fall through */	.globl	exitexit:2:        ljmp $KERN_CODE_SEG,$2b/**************************************************************************MEMSIZE - Determine size of extended memory**************************************************************************/	.globl	memsizememsize:#if 0	pushl	%ebx	pushl	%esi	pushl	%edi	call	_prot_to_real	.code16	movw	$0xe801,%ax	stc	int	$0x15	jc	1f	andl	$0xffff,%eax	andl	$0xffff,%ebx	shll	$6,%ebx	addl	%ebx,%eax	jmp	2f1:	movw	$0x8800,%ax	int	$0x15	andl	$0xffff,%eax2:	movl	%eax,%esi	DATA32 call	_real_to_prot	.code32	movl	%esi,%eax	popl	%edi	popl	%esi	popl	%ebx#else	mov	$32768,%eax#endif	ret/**************************************************************************XSTART - Transfer control to the kernel just loaded**************************************************************************/	.code16	.globl _int08_handler_int08_handler:	movb	$0x20, %al	outb	%al, $0x20	iret	.globl _int10_handler_int10_handler:	cmp	$0x3, %ah	jnz	_int10_04	mov	$0x0, %dx	mov	$0x0, %cx	iret_int10_04:	cmp	$0x4, %ah	jnz	_int10_05	mov	$0x0, %ah	iret_int10_05:	cmp	$0x5, %ah	jnz	_int10_08	mov	$0x0, %al	iret_int10_08:	cmp	$0x8, %ah	jnz	_int10_0D	mov 	$0x20, %al	mov 	$0x7,  %ah	iret_int10_0D:	cmp	$0xD, %ah	jnz	_int10_0F	mov	$0x0, %al	iret_int10_0F:	cmp	$0xF, %ah	jnz	_int10_XX	mov	$0xb, %al	mov	$80, %ah	mov	$0, %bh_int10_XX:	iret		.globl _int11_handler_int11_handler:	mov	$0x22, %ax	iret		.globl _int12_handler_int12_handler:	mov	$640, %ax	iret		.globl _int13_handler_int13_handler:	clc	mov	$0, %ah	iret	.globl _int14_handler_int14_handler:	iret	.globl _int15_handler_int15_handler:	cmp	$0xe801,%ax	jz	_int15_008	cmp	$0x0, %ah	jz	_int15_000	cmp	$0x1, %ah	jz	_int15_000	cmp	$0x2, %ah	jz	_int15_000	cmp	$0x3, %ah	jz	_int15_000	cmp	$0xf, %ah	jz	_int15_000	cmp	$0x21, %ah	jz	_int15_000	cmp	$0x40, %ah	jz	_int15_000	cmp	$0x41, %ah	jz	_int15_000	cmp	$0x42, %ah	jz	_int15_000	cmp	$0x43, %ah	jz	_int15_000	cmp	$0x44, %ah	jz	_int15_000	cmp	$0x80, %ah	jz	_int15_001	cmp	$0x81, %ah	jz	_int15_001	cmp	$0x82, %ah	jz	_int15_002	cmp	$0x83, %ah	jz	_int15_003	cmp	$0x84, %ah	jz	_int15_000	cmp	$0x85, %ah	jz	_int15_004	cmp	$0x86, %ah	jz	_int15_003	cmp	$0x87, %ah	jz	_int15_005	cmp	$0x88, %ah	jz	_int15_006	cmp	$0x89, %ah	jz	_int15_005	cmp	$0x90, %ah	jz	_int15_007	cmp	$0xc0, %ah	jz	_int15_000	cmp	$0xc1, %ah	jz	_int15_000	cmp	$0xc2, %ah	jz	_int15_000	cmp	$0xc3, %ah	jz	_int15_000	cmp	$0xc4, %ah	jz	_int15_000	iret_int15_000:	mov	$0x86, %ah	stc	iret_int15_001:	mov	$0, %bx	mov	$0, %cx	iret_int15_002:	mov	$0, %bx	iret_int15_003:	clc	iret_int15_004:	mov	$0, %al	iret_int15_005:	mov	$0, %ah	clc	cmp 	$0, %ah	iret_int15_006:	mov	$0xf000, %ax	iret_int15_007:	stc	iret_int15_008:	clc	mov	$1024, %dx	/* dx -> extended memory size (in 64K chuncks) */	mov	$640, %cx	/* cx -> conventional memory size (in 1 Kbytes chuncks) */	iret	.globl _int16_handler_int16_handler:	cmp	$0x0, %ah	jnz	_int16_01	mov	$0x20, %al	mov 	$0x39, %ah	iret_int16_01:	cmp	$0x1, %ah	jnz	_int16_02	iret_int16_02:	cmp	$0x2, %ah	jnz	_int16_05	mov	$0, %al	iret_int16_05:	cmp	$0x5, %ah	jnz	_int16_10	mov	$0, %al	iret_int16_10:	cmp	$0x10, %ah	jnz	_int16_11	mov	$0x20, %al	mov 	$0x39, %ah	iret_int16_11:	cmp	$0x11, %ah	jnz	_int16_12	iret_int16_12:	cmp	$0x12, %ah	jnz	_int16_XX	mov $0, %ax	iret_int16_XX:	iret	.globl _int17_handler_int17_handler:	mov $0xd0, %ah	iret	.globl _int19_handler_int19_handler:	hlt	iret	.globl _int1A_handler_int1A_handler:	stc	iret	.code32	.globl	xstartxstart:	/* reprogram the PICs so that interrupt are masked */        movb    $0x11,%al	/* ICW1 [ICW4 NEEDED, EDGE TRIGGERED]*/	outb    %al,$0x20        movb    $PIC1_VBS, %al	outb    %al,$0x21        movb    $0x4,%al	outb    %al,$0x21        movb    $0x1,%al	outb    %al,$0x21        movb    $0xff,%al	outb    %al,$0x21	        movb    $0x11,%al	/* ICW1 [ICW4 NEEDED, EDGE TRIGGERED]*/	outb    %al,$0xa0        movb    $PIC2_VBS, %al	outb    %al,$0xa1        movb    $0x2,%al	outb    %al,$0xa1        movb    $0x1,%al	outb    %al,$0xa1        movb    $0xff,%al	outb    %al,$0xa1	pushl	%ebp	movl	%esp,%ebp	pushl	%ebx	pushl	%esi	pushl	%edi	movl	8(%ebp),%eax	movl	%eax,_execaddr	movl	12(%ebp),%ebx	movl	16(%ebp),%ecx	/* bootp record (32bit pointer) */	addl	$28,%ecx	/* ip, udp header */	shll	$12,%ecx	shrw	$12,%cx	call	_prot_to_real	.code16/* MP: add int10 handler */	push	%eax	push	%ebx	push	%es	mov	$0,%ax	mov	%ax,%es	mov	%cs,%ax	shl	$16,%eax	ADDR32 mov	$(_int08_handler-_start),%ax	mov	$0x20,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int10_handler-_start),%ax	mov	$0x40,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int11_handler-_start),%ax	mov	$0x44,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int12_handler-_start),%ax	mov	$0x48,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int13_handler-_start),%ax	mov	$0x4c,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int14_handler-_start),%ax	mov	$0x50,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int15_handler-_start),%ax	mov	$0x54,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int16_handler-_start),%ax	mov	$0x58,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int17_handler-_start),%ax	mov	$0x5c,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int19_handler-_start),%ax	mov	$0x64,%ebx	mov	%eax,%es:(%bx)	ADDR32 mov	$(_int1A_handler-_start),%ax	mov	$0x68,%ebx	mov	%eax,%es:(%bx)	pop	%es	pop	%ebx	pop	%eax/* */	pushl	%ecx		/* bootp record */	pushl	%ebx		/* file header */	movl	$((RELOC<<12)+(1f-RELOC)),%eax	pushl	%eax	ADDR32	LJMPI(_execaddr-_start)1:	addw	$8,%sp		/* XXX or is this 10 in case of a 16bit "ret" */	DATA32 call	_real_to_prot	.code32	popl	%edi	popl	%esi	popl	%ebx	popl	%ebp	ret_execaddr:	.long	0#ifdef	IMAGE_MULTIBOOT/**************************************************************************XEND - Restart Etherboot from the beginning (from protected mode)**************************************************************************/	.globl	xendxend:	cs	lidt	idtarg_realmode-_start+RELOC	cs	lgdt	gdtarg-_start+RELOC#ifdef	GAS291	ljmp	$REAL_CODE_SEG,$1f-RELOC	/* jump to a 16 bit segment */#else	ljmp	$REAL_CODE_SEG,$1f-_start	/* jump to a 16 bit segment */#endif	/* GAS291 */1:	.code16	movw	$REAL_DATA_SEG,%ax	movw	%ax,%ds	movw	%ax,%ss	movw	%ax,%es	/* clear the PE bit of CR0 */	movl	%cr0,%eax	andl	$0!CR0_PE,%eax	movl	%eax,%cr0	/* make intersegment jmp to flush the processor pipeline	 * and reload %cs:%eip (to clear upper 16 bits of %eip).	 */	DATA32 ljmp	$(RELOC)>>4,$2f-_start2:	/* we are in real mode now	 * set up the real mode segment registers : %ds, %ss, %es	 */	movw	%cs,%ax	movw	%ax,%ds	movw	%ax,%es	movw	%ax,%ss	xorl	%esp,%esp	ADDR32 movw	initsp-RELOC,%sp	movw	$0,%ax	movw	%ax,%fs	movw	%ax,%gs	sti	jmp	_start	.code32#endif	/* IMAGE_MULTIBOOT */.global get_csget_cs:	xorl	%eax,%eax	movw	%cs,%ax	ret.global get_dsget_ds:	xorl	%eax,%eax	movw	%ds,%ax	ret.global getspgetsp:	movl	%esp,%eax	/* GET STACK POINTER */	subl	$4, %eax 	/* ACCOUNT FOR RETURN ADDRESS ON */	ret.global get_gdtbaseget_gdtbase:	sub	$8,%esp			/* ALLOCATE ROOM ON THE STACK */	sgdt	(%esp,1)		/*STORE IGDT REGISTER ON STACK */	mov	2(%esp),%eax		/* READ GDT BASE ADDRESS */	mov	$KERN_DATA_SEG,%dx 	/* ASSUME UNIVERSAL DS. */	add	$8,%esp			/* RESTORE STACK */	ret				/* DONE */.global get_gdtsizeget_gdtsize:	sub 	$8,%esp	/* ALLOCATE ROOM ON THE STACK */	sgdt	(%esp,1)	/*STORE IGDT REGISTER ON STACK */	xor	%eax,%eax	mov	2(%esp),%eax	/* READ GDT BASE ADDRESS */	mov	(%ESP),%ax	shr	$3,%ax	add	$8,%esp	/* RESTORE STACK */	ret			/* DONE */.global get_idtbaseget_idtbase:	sub	$8,%esp	sidt   (%esp,1) 	/* STORE IIDT REGISTER ON STACK */	mov	2(%esp),%eax	mov	$KERN_DATA_SEG,%dx	add	$8,%esp	ret.global get_lwget_lw:	xor	%edx,%edx	mov	8(%esp),%eax	mov	4(%esp),%dx	ret	 /**************************************************************************SETJMP - Save stack context for non-local goto**************************************************************************/	.globl	setjmpsetjmp:	mov	4(%esp),%ecx	mov	0(%esp),%edx	mov	%edx,0(%ecx)	mov	%ebx,4(%ecx)	mov	%esp,8(%ecx)	mov	%ebp,12(%ecx)	mov	%esi,16(%ecx)	mov	%edi,20(%ecx)	mov	%eax,24(%ecx)	mov	$0,%eax	ret/**************************************************************************LONGJMP - Non-local jump to a saved stack context**************************************************************************/	.globl	longjmplongjmp:	mov	4(%esp),%edx	mov	8(%esp),%eax	mov	0(%edx),%ecx	mov	4(%edx),%ebx	mov	8(%edx),%esp	mov	12(%edx),%ebp	mov	16(%edx),%esi	mov	20(%edx),%edi	cmp	$0,%eax	jne	1f	mov	$1,%eax1:	mov	%ecx,0(%esp)	ret/**************************************************************************_REAL_TO_PROT - Go from REAL mode to Protected Mode**************************************************************************/	.globl	_real_to_prot_real_to_prot:	.code16	cli	cs	ADDR32 lgdt	gdtarg-_start	movl	%cr0,%eax	orl	$CR0_PE,%eax	movl	%eax,%cr0		/* turn on protected mode */	/* flush prefetch queue, and reload %cs:%eip */	DATA32 ljmp	$KERN_CODE_SEG,$1f1:	.code32	/* reload other segment registers */	movl	$KERN_DATA_SEG,%eax	movl	%eax,%ds	movl	%eax,%es	movl	%eax,%ss	addl	$RELOC,%esp		/* Fix up stack pointer */	xorl	%eax,%eax	movl	%eax,%fs	movl	%eax,%gs	popl	%eax			/* Fix up return address */	addl	$RELOC,%eax	pushl	%eax	ret/**************************************************************************_PROT_TO_REAL - Go from Protected Mode to REAL Mode**************************************************************************/	.globl	_prot_to_real_prot_to_real:	.code32	popl	%eax	subl	$RELOC,%eax		/* Adjust return address */	pushl	%eax	subl	$RELOC,%esp		/* Adjust stack pointer */#ifdef	GAS291	ljmp	$REAL_CODE_SEG,$1f-RELOC	/* jump to a 16 bit segment */#else	ljmp	$REAL_CODE_SEG,$1f-_start	/* jump to a 16 bit segment */#endif	/* GAS291 */1:	.code16	movw	$REAL_DATA_SEG,%ax	movw	%ax,%ds	movw	%ax,%ss	movw	%ax,%es	movw	%ax,%fs	movw	%ax,%gs	cli	/* clear the PE bit of CR0 */	movl	%cr0,%eax	andl	$0!CR0_PE,%eax	movl	%eax,%cr0	/* make intersegment jmp to flush the processor pipeline	 * and reload %cs:%eip (to clear upper 16 bits of %eip).	 */	DATA32 ljmp	$(RELOC)>>4,$2f-_start2:	/* we are in real mode now	 * set up the real mode segment registers : %ds, $ss, %es	 */	movw	%cs,%ax	movw	%ax,%ds	movw	%ax,%es	movw	%ax,%ss#if 0	sti#endif	DATA32 ret	/* There is a 32 bit return address on the stack */	.code32/**************************************************************************GLOBAL DESCRIPTOR TABLE**************************************************************************/	.align	4Idt_Reg:	.word 0x3ff	.long 0	.align	4_gdt:gdtarg:Gdt_Table:	.word	0x27			/* limit */	.long	_gdt			/* addr */	.word	0_pmcs:	/* 32 bit protected mode code segment */	.word	0xffff,0	.byte	0,0x9f,0xcf,0_pmds:	/* 32 bit protected mode data segment */	.word	0xffff,0	.byte	0,0x93,0xcf,0_rmcs:	/* 16 bit real mode code segment */	.word	0xffff,(RELOC&0xffff)	.byte	(RELOC>>16),0x9b,0x00,(RELOC>>24)_rmds:	/* 16 bit real mode data segment */	.word	0xffff,(RELOC&0xffff)	.byte	(RELOC>>16),0x93,0x00,(RELOC>>24)	.align	4RUN_GDT: 			/* POINTER TO GDT IN RAM */	 .byte	 0x7f,0		/* [BSP_GDT_NUM*8]-1 */	 .long	 Gdt_Table	.align	4	.section ".rodata"err_not386:	.ascii	"Etherboot/32 requires 386+"	.byte	0x0d, 0x0aerr_not386_end:days:	.long	0irq_num: .long        .data	.align	4        .org 2048.global stktopstktop:	.long.section ".armando"/* 

⌨️ 快捷键说明

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