mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-12 14:26:34 +00:00
757 lines
14 KiB
ArmAsm
757 lines
14 KiB
ArmAsm
/* #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,$1f
|
||
1:
|
||
|
||
/* 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 exit
|
||
exit:
|
||
2:
|
||
ljmp $KERN_CODE_SEG,$2b
|
||
|
||
/**************************************************************************
|
||
MEMSIZE - Determine size of extended memory
|
||
**************************************************************************/
|
||
.globl memsize
|
||
memsize:
|
||
#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 2f
|
||
1:
|
||
movw $0x8800,%ax
|
||
int $0x15
|
||
andl $0xffff,%eax
|
||
2:
|
||
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 xstart
|
||
xstart:
|
||
/* 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 xend
|
||
xend:
|
||
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-_start
|
||
2:
|
||
/* 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_cs
|
||
get_cs:
|
||
xorl %eax,%eax
|
||
movw %cs,%ax
|
||
ret
|
||
|
||
.global get_ds
|
||
get_ds:
|
||
xorl %eax,%eax
|
||
movw %ds,%ax
|
||
ret
|
||
|
||
.global getsp
|
||
getsp:
|
||
movl %esp,%eax /* GET STACK POINTER */
|
||
subl $4, %eax /* ACCOUNT FOR RETURN ADDRESS ON */
|
||
ret
|
||
|
||
.global get_gdtbase
|
||
get_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_gdtsize
|
||
get_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_idtbase
|
||
get_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_lw
|
||
get_lw:
|
||
xor %edx,%edx
|
||
mov 8(%esp),%eax
|
||
mov 4(%esp),%dx
|
||
ret
|
||
|
||
/**************************************************************************
|
||
SETJMP - Save stack context for non-local goto
|
||
**************************************************************************/
|
||
.globl setjmp
|
||
setjmp:
|
||
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 longjmp
|
||
longjmp:
|
||
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,%eax
|
||
1: 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,$1f
|
||
1:
|
||
.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-_start
|
||
2:
|
||
/* 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 4
|
||
Idt_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 4
|
||
RUN_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, 0x0a
|
||
err_not386_end:
|
||
|
||
days: .long 0
|
||
irq_num: .long
|
||
|
||
.data
|
||
.align 4
|
||
.org 2048
|
||
.global stktop
|
||
stktop:
|
||
.long
|
||
|
||
.section ".armando"
|
||
/* <20> <20> <20> <20> <20> <20> <20> <20>1:::::::::2:::::::::3:::::::3 */
|
||
/* <20> <20> <20> <20>12345678901234567890123456789012345678 */
|
||
/* <20> <20> <20> v----+----v----+----v----+----v----+--- */
|
||
|
||
.global EtherbootString
|
||
EtherbootString:
|
||
.ascii "EtherBoot MPCC " /* fw identifier */
|
||
|
||
.byte 0, 0 /* mandatory hole */
|
||
|
||
.long _start /* entry point */
|
||
.word 0
|
||
.byte 'E' /* type */
|
||
.byte 0 /* selector */
|
||
.word 0 /* CRC */
|