Преглед на файлове

PROTECTED MODE BABY

lets32bit
Jakob Kjær-Kammersgaard преди 5 години
родител
ревизия
41d4b4a7fb
променени са 3 файла, в които са добавени 170 реда и са изтрити 61 реда
  1. +114
    -27
      bootloader.nasm
  2. +55
    -33
      bootloader_macros.inc
  3. +1
    -1
      build

+ 114
- 27
bootloader.nasm Целия файл

@ -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

+ 55
- 33
bootloader_macros.inc Целия файл

@ -16,37 +16,59 @@
; GDT Stuff
%define Data 0000b
%define DataMutable 0010b
%define DataShrink 0100b
%define DataShrinkMutable 0110b
%define Code 1000b
%define CodeRead 1010b
%define CodeOnlyOwnPriv 1100b
%define CodeOnlyOwnPrivRead 1110b
; Each define here is for a specific flag in the descriptor.
; Refer to the intel documentation for a description of what each one does.
%define SEG_DESCTYPE(x) ((x) << 4) ; Descriptor type (0 for system, 1 for code/data)
%define SEG_PRES(x) ((x) << 7) ; Present
%define SEG_SAVL(x) ((x) << 12) ; Available for system use
%define SEG_LONG(x) ((x) << 13) ; Long mode
%define SEG_SIZE(x) ((x) << 14) ; Size (0 for 16-bit, 1 for 32)
%define SEG_GRAN(x) ((x) << 15) ; Granularity (0 for 1B - 1MB, 1 for 4KB - 4GB)
%define SEG_PRIV(x) (((x) & 3) << 5) ; Set privilege level (0 - 3)
%define SEG_DATA_RD 0000b ; Read-Only
%define SEG_DATA_RDA 0001b ; Read-Only, accessed
%define SEG_DATA_RDWR 0010b ; Read/Write
%define SEG_DATA_RDWRA 0011b ; Read/Write, accessed
%define SEG_DATA_RDEXPD 0100b ; Read-Only, expand-down
%define SEG_DATA_RDEXPDA 0101b ; Read-Only, expand-down, accessed
%define SEG_DATA_RDWREXPD 0110b ; Read/Write, expand-down
%define SEG_DATA_RDWREXPDA 0111b ; Read/Write, expand-down, accessed
%define SEG_CODE_EX 1000b ; Execute-Only
%define SEG_CODE_EXA 1001b ; Execute-Only, accessed
%define SEG_CODE_EXRD 1010b ; Execute/Read
%define SEG_CODE_EXRDA 1011b ; Execute/Read, accessed
%define SEG_CODE_EXC 1100b ; Execute-Only, conforming
%define SEG_CODE_EXCA 1101b ; Execute-Only, conforming, accessed
%define SEG_CODE_EXRDC 1110b ; Execute/Read, conforming
%define SEG_CODE_EXRDCA 1111b ; Execute/Read, conforming, accessed
%macro GDT_ENTRY 4 ; GDTIndex Base Limit Attributes
mov word [es:GDT_BASE+(%1*8)+0], %3 & 0xffff ; limit 0:15
mov word [es:GDT_BASE+(%1*8)+2], %2 & 0xffff ; base 0:15
mov word [es:GDT_BASE+(%1*8)+4], ((%4 << 8) & 0xff00) | ((%2 >> 16) & 0x00ff) ; access | base 16:23
mov word [es:GDT_BASE+(%1*8)+6], ((%2 >> 16) & 0xff00) | ((%4 >> 16) & 0x00f0) | ((%3 >> 16) & 0x000f) ; base 24:31 | flags | limit 16:19
%endmacro
; %define DataAcc 0001b
; %define DataMutableAcc 0011b
; %define DataShrinkAcc 0101b
; %define DataShrinkMutableAcc 0111b
; %define CodeAcc 1001b
; %define CodeReadAcc 1011b
; %define CodeOnlyOwnPrivAcc 1101b
; %define CodeOnlyOwnPrivReadAcc 1111b
%macro GDT_NULL_ENTRY 1 ; address
%assign address %1
lea di, [address]
xor ax, ax
mov cx, 4
rep stosw
%endmacro
%macro GDT_ENTRY 6 ; address base limit type privilege bits32
%assign address %1
%assign base %2
%assign limit %3
%assign type (%4 & 0xf)
%assign reserved (1<<4)
%assign privilege ((%5 & 0x3) << 5)
%assign present (1<<7)
%assign access (present | privilege | reserved | type)
%assign bits32 ((%6 & 1) << 2)
%assign granularity (1<<3)
%assign flags (granularity | bits32)
%assign limit_0_15 (limit & 0xffff)
%assign limit_16_19 ((limit >> 16) & 0xf)
%assign base_0_15 (base & 0xffff)
%assign base_16_23 ((base >> 16) & 0xff)
%assign base_24_31 ((base >> 24) & 0xff)
mov WORD [address + 0], limit_0_15
mov WORD [address + 2], base_0_15
mov WORD [address + 4], base_16_23 | (access << 8)
mov WORD [address + 6], limit_16_19 | (flags << 4) | (base_24_31 << 8)
%endmacro
%define GDT_Selector(DescriptorIndex, TableIndicator, RequestorPrivLevel) ((DescriptorIndex << 3) | ((TableIndicator & 1) << 2) | (RequestorPrivLevel & 0x3))

+ 1
- 1
build Целия файл

@ -9,7 +9,7 @@ BuildSteps=(
"dd conv=notrunc if=./boot.bin of=./Floppy.img"
# "gcc -O0 -o ./VGA/grdemo.o ./VGA/grdemo.c"
# "objcopy -O binary ./VGA/grdemo.o ./grdemo.bin"
"qemu-system-x86_64 -drive format=raw,file=Floppy.img"
"qemu-system-x86_64 -vga cirrus -drive format=raw,file=Floppy.img"
# "bochs"
)

Зареждане…
Отказ
Запис