|
|
@ -2,7 +2,14 @@ BITS 16 |
|
|
|
%include "bootloader_macros.inc" |
|
|
|
%define STAGE1_BASE 0x7c00 |
|
|
|
%define STAGE2_BASE (STAGE1_BASE + 0x200) |
|
|
|
%define GDT_BASE 0x0800 |
|
|
|
%define PROTECED_MODE_BASE (STAGE2_BASE + 0x200) |
|
|
|
%define GDT 0x0800 |
|
|
|
%define GDT_CodeSegIndex 1 |
|
|
|
%define GDT_DataSegIndex 2 |
|
|
|
%define GDT_CodeSegmentSelector GDT_Selector(GDT_CodeSegIndex, 0, 0) |
|
|
|
%define GDT_DataSegmentSelector GDT_Selector(GDT_DataSegIndex, 0, 0) |
|
|
|
%define VIDEO 0xB8000 |
|
|
|
|
|
|
|
|
|
|
|
%define STACK_POINTER_MAX STAGE1_BASE-2 ; Stack grows downwards from right under stage_1 |
|
|
|
|
|
|
@ -114,9 +121,6 @@ NoChange: |
|
|
|
jmp DiskReadError |
|
|
|
.BreakTryReadLoop: |
|
|
|
|
|
|
|
mov ax, 0x0013 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors |
|
|
|
int 0x10 ; Video BIOS interrupt |
|
|
|
|
|
|
|
jmp STAGE2_BASE |
|
|
|
|
|
|
|
DiskReadError: |
|
|
@ -172,28 +176,81 @@ Stage2: |
|
|
|
mov si, A20Status |
|
|
|
call PrintString |
|
|
|
|
|
|
|
; Setup GDT |
|
|
|
|
|
|
|
xor ax, ax |
|
|
|
mov cx, 4 |
|
|
|
rep stosw |
|
|
|
; mov ah, 0x05 ; switch display page |
|
|
|
; mov al, 0x00 ; page 0 |
|
|
|
; int 0x10 |
|
|
|
|
|
|
|
%if 0 |
|
|
|
mov ax, 0x4f02 ; VESA mode |
|
|
|
mov bx, 0x0301 ; 132 cols by 60 rows |
|
|
|
int 0x10 ; Video BIOS interrupt |
|
|
|
%elif 0 |
|
|
|
mov ax, 0x0013 ; AH=0 (Change video mode), AL=13h (Mode) = 320x200 - 256 colors |
|
|
|
mov bx, 0 |
|
|
|
int 0x10 ; Video BIOS interrupt |
|
|
|
%else |
|
|
|
mov ax, 0x0003 |
|
|
|
mov bx, 0 |
|
|
|
int 0x10 |
|
|
|
%endif |
|
|
|
|
|
|
|
; pusha |
|
|
|
; mov ax, 0xA000 |
|
|
|
; mov es, ax |
|
|
|
; mov ax, 7 |
|
|
|
; es mov [320*100 + 100], ax |
|
|
|
; mov ax, 0xB800 |
|
|
|
; mov es, ax |
|
|
|
; es mov WORD [0], 0x0748 |
|
|
|
; es mov WORD [2], 0x0769 |
|
|
|
; popa |
|
|
|
; HALT |
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
; Global Descriptor Table ; |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
%assign GDT_SIZE 0 |
|
|
|
|
|
|
|
GDT_NULL_ENTRY GDT |
|
|
|
%assign GDT_SIZE (GDT_SIZE+8) |
|
|
|
|
|
|
|
GDT_ENTRY (GDT + (GDT_CodeSegIndex*8)), 0x00000000, 0xffffffff, CodeRead, 0, 1 |
|
|
|
%assign GDT_SIZE (GDT_SIZE+8) |
|
|
|
|
|
|
|
GDT_ENTRY 1, 0x0000, 0xffff, (SEG_CODE_EXRD|SEG_DESCTYPE(1)|SEG_PRES(1)|SEG_SAVL(0)|SEG_LONG(0)|SEG_SIZE(1)|SEG_GRAN(1)|SEG_PRIV(0)) |
|
|
|
GDT_ENTRY 2, 0x0000, 0xffff, (SEG_DATA_RDWR|SEG_DESCTYPE(1)|SEG_PRES(1)|SEG_SAVL(0)|SEG_LONG(0)|SEG_SIZE(1)|SEG_GRAN(1)|SEG_PRIV(0)) |
|
|
|
GDT_ENTRY (GDT + (GDT_DataSegIndex*8)), 0x00000000, 0xffffffff, DataMutable, 0, 1 |
|
|
|
%assign GDT_SIZE (GDT_SIZE+8) |
|
|
|
|
|
|
|
; GDT_ENTRY 1, 0x0000, 0xffff, (SEG_CODE_EXRD|SEG_DESCTYPE(1)|SEG_PRES(1)|SEG_SAVL(0)|SEG_LONG(0)|SEG_32Bit(1)|SEG_GRAN(1)|SEG_PRIV(0)) ; 32 bit |
|
|
|
; GDT_ENTRY 2, 0x0000, 0xffff, (SEG_DATA_RDWR|SEG_DESCTYPE(1)|SEG_PRES(1)|SEG_SAVL(0)|SEG_LONG(0)|SEG_32Bit(1)|SEG_GRAN(1)|SEG_PRIV(0)) ; 32 bit |
|
|
|
|
|
|
|
cli |
|
|
|
lgdt [GDTR] |
|
|
|
lgdt [GDT_Record] |
|
|
|
|
|
|
|
xchg bx, bx |
|
|
|
mov eax, cr0 |
|
|
|
or al, 1 ; set PE (Protection Enable) bit in CR0 (Control Register 0) |
|
|
|
mov cr0, eax |
|
|
|
xchg bx, bx |
|
|
|
|
|
|
|
jmp 8:ProtectedModeBaby ; 8: is for the first descriptor in the GDT that is not the null-descriptor |
|
|
|
jmp ClearPrefetchQueue |
|
|
|
nop |
|
|
|
nop |
|
|
|
ClearPrefetchQueue: |
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
;; Manually assembled long jump |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
db 0x66 ; 32bit override |
|
|
|
db 0xea ; Long jump |
|
|
|
dd PROTECED_MODE_BASE ; Absolute address |
|
|
|
dw GDT_CodeSegmentSelector ; Descriptor Selector |
|
|
|
|
|
|
|
; jmp GDT_CodeSegmentSelector:ProtectedModeBaby ; 8: is for the first descriptor in the GDT that is not the null-descriptor |
|
|
|
HALT |
|
|
|
|
|
|
|
GDT_Record: |
|
|
|
dw GDT_SIZE - 1 ; Size of GDT in bytes minus 1 |
|
|
|
dd GDT ; Linear address of GDT |
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
%include "bootloader_A20.nasm" |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
@ -201,25 +258,55 @@ SecondStageString: db "This is the second stage!", 13, 10, 0 |
|
|
|
EnablingA20Str: db "Enabling A20...", 13, 10, 0 |
|
|
|
A20Status: db "A20_Enabled=" |
|
|
|
.Bit: db '0', 13, 10, 0 |
|
|
|
GDTR: |
|
|
|
dw 24 ; Size of GDT in bytes minus 1 |
|
|
|
dd GDT_BASE ; Linear address of GDT |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
|
|
|
|
times 512-($-$$) db 0 |
|
|
|
|
|
|
|
BITS 32 |
|
|
|
segment ProtectedModeBaby vstart=0x8000 |
|
|
|
segment ProtectedModeBaby vstart=PROTECED_MODE_BASE |
|
|
|
ProtectedModeBaby: |
|
|
|
xchg bx, bx |
|
|
|
mov eax, (1<<20)-1 |
|
|
|
add eax, 7 |
|
|
|
; Code segment updated by the long jump here |
|
|
|
|
|
|
|
mov dl, 7 ; Grey color. |
|
|
|
mov byte [0xA0000+edi], dl ; And we put the pixel |
|
|
|
|
|
|
|
; mov si, ProtectedWelcomeStr |
|
|
|
; call PrintString ; Yes, we cannot use BIOS from proteced mode |
|
|
|
; Update Other Segments |
|
|
|
mov ax, GDT_DataSegmentSelector |
|
|
|
mov ds, ax |
|
|
|
mov ss, ax |
|
|
|
mov es, ax |
|
|
|
mov fs, ax |
|
|
|
mov gs, ax |
|
|
|
|
|
|
|
; Setup stack |
|
|
|
mov esp, 0xffffffff |
|
|
|
|
|
|
|
mov ecx, 2000 |
|
|
|
lea edi, [VIDEO] |
|
|
|
xor ax, ax |
|
|
|
L1: |
|
|
|
mov ah, cl |
|
|
|
mov WORD [edi], ax |
|
|
|
inc edi |
|
|
|
inc edi |
|
|
|
loop L1 |
|
|
|
|
|
|
|
WriteProtectedModeString: |
|
|
|
cld |
|
|
|
lea esi, [ProtectedWelcomeStr] |
|
|
|
lea edi, [VIDEO] |
|
|
|
.print_loop: |
|
|
|
mov al, BYTE [esi] |
|
|
|
test al, al |
|
|
|
jz .break_print_loop |
|
|
|
mov BYTE [edi], al |
|
|
|
mov BYTE [edi+1], 0xf9 |
|
|
|
inc esi |
|
|
|
inc edi |
|
|
|
inc edi |
|
|
|
jmp .print_loop |
|
|
|
.break_print_loop: |
|
|
|
|
|
|
|
HALT |
|
|
|
|
|
|
|
; ProtectedWelcomeStr: db "Protected Mode Baby!", 13, 10, 0 |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
;; Strings |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;; |
|
|
|
ProtectedWelcomeStr: db "Protected Mode Baby! WHOOOOO YEAH!", 13, 10, 0 |