-OBJS=multiboot_c.o multiboot_asm.o console.o minilib.o loader.o
+OBJS=multiboot_c.o multiboot_asm.o console.o minilib.o realmode.o loader.o
CC=gcc
CFLAGS=-nostdlib -I../include -I. -fno-builtin -nostdinc
multiboot: $(OBJS)
ld -o multiboot $(OBJS) -Ttext=0x100000
+
+realmode.bin: realmode.asm
+ nasm -o realmode.bin realmode.asm
+
+realmode.o: realmode.bin
+ objcopy -I binary -B i386 -O elf32-i386 realmode.bin realmode.o
#include "console.h"
+extern char _binary_realmode_bin_start[];
+extern int _binary_realmode_bin_size;
+
struct mb_info
{
unsigned long flags;
unsigned short *grubptr = 0x7CFE;
int i;
+ void (*realmode)() = 0x4000;
+
puts("Magic is: ");
puthex(magic);
puts("\nMultiboot header is: ");
load_elf(wee->mods[0].mod_start, wee->mods[0].mod_end - wee->mods[0].mod_start);
-
- while (1)
- ;
+ puts("Now returning to real mode.\n");
+ memcpy(0x4000, _binary_realmode_bin_start, (int)&_binary_realmode_bin_size);
+ realmode(); // goodbye!
}
--- /dev/null
+ [bits 32] ; Starts in 32 bit mode, then will drop back later.
+ org 0x4000
+entry:
+ cli
+ ; clean up 32 bit regs
+ mov eax, 0x0
+ mov ebx, 0x0
+ mov ecx, 0x0
+ mov edx, 0x0
+ mov esi, 0x0
+ mov edi, 0x0
+ mov ebp, 0x0
+ mov esp, 0x0
+
+ lgdt [gdtp]
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ jmp 0x8:nextp ; Clear CS bits now too
+
+nextp:
+
+ mov eax, cr0
+ xor eax, 0x1 ; Clear PE
+ mov cr0, eax
+
+ jmp 0x0:nowreal ; and jmp away
+
+
+ [bits 16]
+nowreal:
+ mov long eax, 0x0000
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ mov sp, 0xFFFF ; set up the stack
+
+ mov al, 0xAB
+ out 0x80, al
+
+ cli
+ lidt [idtp]
+
+ mov si, RETMSG
+ call disp
+
+ int 0x19 ; warm boot without clearing RAM.
+ call handload_drive ; hopefully shouldn't happen
+ ; ok, we give up
+ cli
+halt: hlt
+ jmp halt
+
+disp:
+ lodsb
+ or al, al
+ jz .done
+ mov ah, 0x0E
+ mov bx, 0x0007
+ int 0x10
+ jmp disp
+.done:
+ ret
+
+; handload_drive should be unnecessary; int 19 should take care of it for
+; us...
+handload_drive:
+ mov ax, 0x07C0
+ mov es, ax
+ mov ax, 0x0201 ; read one sector
+ mov bx, 0x0000 ; to the normal location
+ mov cx, 0x0001 ; disk sector 1
+ mov dx, 0x0080 ; drive 0
+ int 0x13
+ jc readerr
+
+ mov si, READSUCC
+ call disp
+
+ jmp 0x7C0:0x0 ; and return control to grub!
+readerr:
+ mov si, READFAIL
+ call disp
+ ret
+
+RETMSG db "SMM installer finished, booting your system of choice.",10,13,0
+READSUCC db "Read successful; rebooting into boot sector.",10,13,0
+READFAIL db "Boot disk read failure; system halted.",10,13,0
+
+
+idtp db 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00
+
+gdtp dw 0x1F
+ dd gdt
+
+gdt dd 0, 0
+ dd 0x0000FFFF, 0x00009e00 ; CS
+ dd 0x0000FFFF, 0x00009300 ; DS