#define STACKADDR 0xe000 /* Needs to be end of bss + stacksize */
#define KERN_CODE_SEG 0x08
#define KERN_DATA_SEG 0x10
#define REAL_MODE_SEG 0x18
#define opsize .byte 0x66
#define addrsize .byte 0x67
/* At entry, the processor is in 16 bit real mode and the code is being
* executed from an address it was not linked to. Code must be pic and
* 32 bit sensitive until things are fixed up.
.word 0xaa55 /* bios extension signature */
.byte (ROMSIZE>>9) /* no. of 512B blocks */
jmp 1f /* enter from bios here */
.byte 0xa1 /* MOV 0x304,%ax */
.byte 0x3d /* CMP $0x4d52, %ax == 'MR' */
.byte 0xa1 /* MOV 0x64, %ax */
.byte 0xa3 /* MOV %ax, 0x300 */
.byte 0xa1 /* MOV 0x66, %ax */
.byte 0xa3 /* MOV %ax, 0x302 */
.byte 0xb8 /* MOV $_start-RELOCADDR, %ax */
.byte 0xa3 /* MOV %ax, 0x64 */
.byte 0xa3 /* MOV %ax, 0x66 */
.byte 0xb8 /* MOV 'MR',%ax */
.byte 0xa3 /* MOV %ax, 0x304 */
/**************************************************************************
START - Where all the fun begins....
**************************************************************************/
#ifdef BOOTROM /* relocate ourselves */
xor %esi, %esi /* zero for ROMs */
.byte 0xbe /* MOV $0x100,%si -- 100h for .COM */
.byte 0xb8 /* MOV $RELOCADDR>>4, %ax */
.byte 0xb9 /* MOV $ROMSIZE, %cx */
ljmp $(RELOC>>4),$1f-RELOC /* Jmp to RELOC:1f */
.byte 0xb8 /* MOV $STACKADDR, %ax */
.byte 0xa1 /* MOV 0x302, %ax */
.byte 0xa1 /* MOV 0x300, %ax */
/**************************************************************************
**************************************************************************/
/**************************************************************************
PUTCHAR - Print a character
**************************************************************************/
/**************************************************************************
GETCHAR - Get a character
**************************************************************************/
/**************************************************************************
ISKEY - Check for keyboard interrupt
**************************************************************************/
* C library -- _setjmp, _longjmp
* will generate a "return(v)" from the last call to
* by restoring registers from the stack.
* The previous signal state is restored.
/**************************************************************************
___MAIN - Dummy to keep GCC happy
**************************************************************************/
/**************************************************************************
REAL_TO_PROT - Go from REAL mode to Protected Mode
**************************************************************************/
mov %eax, %cr0 /* turn on protected mode */
/* jump to relocation, flush prefetch queue, and reload %cs */
/* reload other segment registers */
movl $KERN_DATA_SEG, %eax
add $RELOC,%esp /* Fix up stack pointer */
pop %eax /* Fix up return Address */
/**************************************************************************
PROT_TO_REAL - Go from Protected Mode to REAL Mode
**************************************************************************/
sub $RELOC,%eax /* Adjust return address */
sub $RELOC,%esp /* Adjust stack pointer */
ljmp $REAL_MODE_SEG, $1f /* jump to a 16 bit segment */
/* clear the PE bit of CR0 */
/* make intersegment jmp to flush the processor pipeline
ljmp $(RELOC)>>4, $2f-RELOC
/* we are in real mode now
* set up the real mode segment registers : DS, SS, ES
/**************************************************************************
**************************************************************************/