mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-12 22:36:28 +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 */
|