Fixed everything to work with the new libc

This commit is contained in:
2024-10-26 14:40:18 +02:00
parent 21c59b28f7
commit 5d420b0d68
14 changed files with 43 additions and 27 deletions
+472
View File
@@ -0,0 +1,472 @@
[bits 16]
[org 0x7e00]
%define STAGE3_LOC 0x50000
%define MODE_INFO_BLOCK_LOC 0x6000
start:
mov [driveNum], dl
; Physical memory map setup
xor ax, ax
mov es, ax
memMapEntries equ 0x7000
getMemoryMap:
mov di, memMapEntries + 4 ; 4 bytes after memMapEntries
xor ebx, ebx
xor bp, bp
mov edx, "PAMS" ; SMAP in little endian
mov eax, 0xe820
mov dword [es:di+20], 1 ; Force valid ACPI 3.X entry
mov ecx, 24
int 0x15
jc .error
cmp eax, "PAMS"
jne .error
test ebx, ebx
jnz .start
.error:
stc
jmp inputGfx
.nextEntry:
mov edx, "PAMS" ; In case BIOS messes with edx
mov ecx, 24
mov eax, 0xe820
int 0x15
.start:
jcxz .skipEntry
mov ecx, [es:di+8] ; Low 32 bits of length
or ecx, [es:di+12] ; High 32 bits of length
jz .skipEntry
; Valid entry
inc bp
add di, 24 ; Next entry
.skipEntry:
test ebx, ebx
jz .done
jmp .nextEntry
.done:
mov [memMapEntries], bp
clc
;; Get graphics values from user (resolution etc.)
inputGfx:
xor ecx, ecx
cmp word [width], 0 ; Values already set
jne vbeSetup
mov si, gfxChooseMsg
call print
call getNumber ; Stores input value in bx
mov [width], bx
mov si, gfxHeightMsg
call print
call getNumber
mov [height], bx
mov si, gfxBppMsg
call print
call getNumber
mov [bpp], bx
vbeSetup:
; Setup VBE info
xor ax, ax
mov es, ax
mov ax, 0x4f00
mov di, vbeInfoBlock
int 0x10
cmp ax, 0x4f
jne error
mov ax, word [vbeInfoBlock.videoModePtr]
mov [offset], ax
mov ax, word [vbeInfoBlock.videoModePtr+2]
mov [_segment], ax
mov fs, ax
mov si, [offset]
;; Get next VBE mode
.findMode:
mov dx, [fs:si]
inc si
inc si
mov [offset], si
mov [mode], dx
cmp dx, 0xffff ; Indicates end of modes
je .endOfModes
mov ax, 0x4f01 ; Get VBE mode info
mov cx, [mode]
mov di, modeInfoBlock
int 0x10
cmp ax, 0x4f
jne error
; Print values (Debug)
; mov ax, [modeInfoBlock.xRes]
; ror ax, 8
; call printHex
; ror ax, 8
; call printHex
; mov ax, 0x0e20
; int 0x10
; mov ax, [modeInfoBlock.yRes]
; ror ax, 8
; call printHex
; ror ax, 8
; call printHex
; mov ax, 0x0e20
; int 0x10
; xor ax, ax
; mov al, [modeInfoBlock.bpp]
; call printHex
; mov ax, 0x0e20
; int 0x10
; mov al, 0x0a
; int 0x10
; mov al, 0x0d
; int 0x10
; Check if it is the right mode
mov ax, [width]
cmp ax, [modeInfoBlock.xRes]
jne .nextMode
mov ax, [height]
cmp ax, [modeInfoBlock.yRes]
jne .nextMode
mov al, [bpp]
cmp al, [modeInfoBlock.bpp]
jne .nextMode
; Set VBE mode
mov ax, 0x4f02
mov bx, [mode]
or bx, 0x4000 ; Set 14th bit to 1
xor di, di
int 0x10
cmp ax, 0x4f
jne error
jmp loadGDT
.nextMode:
mov ax, [_segment]
mov fs, ax
mov si, [offset]
jmp .findMode
.endOfModes:
mov ax, 0x03
int 0x10 ; Clear screen
mov si, gfxModeNotFoundErr
call print
mov word [width], 0 ; Unset values
jmp inputGfx
error:
mov si, vbeErr
call print
cli
hlt
;; Load the global descriptor table (GDT)
loadGDT:
cli
lgdt [GDT_Descriptor]
; Enable protected mode
mov eax, cr0
or eax, 1
mov cr0, eax
; Far jump to 32 bit mode!!
jmp CODE_SEG:protected_start
;;
;; Prints a hex byte
;; al - value to print
;;
printHex:
push ax
push bx
mov bh, 2
mov bl, al
and al, 0xf0
ror al, 4
mov ah, 0x0e ; For printing
.printNibble:
cmp al, 10
jl .print
add al, 39
.print:
add al, 48 ; ASCII Char
int 0x10
dec bh
jz .done
mov al, bl
and al, 0x0f
jmp .printNibble
.done:
pop bx
pop ax
ret
;;
;; Prints a null terminated string
;; si - pointer to string
;;
print:
push ax
mov ah, 0x0e
.loop:
lodsb ; mov al, [si] inc si
cmp al, 0
je .done
int 0x10
jmp .loop
.done:
pop ax
ret
;;
;; Reads a base 10 number as input from user
;; Returns:
;; bx - number read
;;
getNumber: ; TODO: if user enters a number that overflows (n > 0xffff) shit breaks
push cx
push ax
push dx
xor bx, bx
mov cx, 10
.nextDigit:
xor ah, ah
int 0x16
mov ah, 0x0e
cmp al, 0x08 ; Backspace
je .backspace
cmp al, 0x0d ; Enter
je .enter
cmp al, '0' ; Make sure user entered a number
jl .nextDigit
cmp al, '9'
jg .nextDigit
int 0x10 ; Print the digit
sub al, '0' ; Convert to integer
mov ah, 0
imul bx, bx, 10 ; bx *= 10
add bx, ax ; bx += ax
jmp .nextDigit
.backspace:
cmp bx, 0 ; Check if we can backspace
je .nextDigit
int 0x10 ; go back one space
mov ax, bx
xor dx, dx
div cx ; dx:ax / cx -> ax = result, dx = remainder
mov bx, ax
mov ah, 0x0e
mov al, ' '
int 0x10
mov al, 0x08
int 0x10
jmp .nextDigit
.enter:
pop dx
pop ax
pop cx
ret
;; 32 Bit entry code
[bits 32]
protected_start:
; Set up data and stack segments
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
; Set up the stack pointer in protected mode
mov ebp, 0x90000
mov esp, ebp
; Store VBE Mode Info Block in memory
mov esi, modeInfoBlock
mov edi, MODE_INFO_BLOCK_LOC ; Destination
mov ecx, 64 ; 64 * 4 = 256B (size of modeInfoBlock)
rep movsd
; Perform The far jump
jmp CODE_SEG:STAGE3_LOC
;; Data
driveNum: db 0
vbeErr: db "VBE Error!", 0
acpiFuncErr: db "ACPI Function not supported!", 0
gfxChooseMsg: db "Please enter desired values" ; No NULL terminator, we want to print gfxWidthMsg right after anyway
gfxWidthMsg: db 0x0a, 0x0d, "Width: ", 0
gfxHeightMsg: db 0x0a, 0x0d, "Height: ", 0
gfxBppMsg: db 0x0a, 0x0d, "Bits Per Pixel: ", 0
gfxModeNotFoundErr: db "Mode not found! ", 0
;; GDT
GDT:
.start:
.nullDescriptor: ; No clue why this exists
dd 0
dd 0
.codeDescriptor: ; Memory for code
dw 0xffff ; First 16 bits of limit
dw 0 ; 16 bits +
db 0 ; + 8 bits = 24 bits
db 0b10011010 ; p, dpl, s, type flags
db 0b11001111 ; Other flags, last 4 bits of limit
db 0 ; Base
.dataDescriptor: ; Memory for data
dw 0xffff ; First 16 bits of limit
dw 0 ; 16 bits +
db 0 ; + 8 bits = 24 bits
db 0b10010010 ; p, dpl, s, type flags
db 0b11001111 ; Other flags, last 4 bits of limit
db 0 ; Base
.end:
GDT_Descriptor:
dw GDT.end - GDT.start - 1 ; Size
dd GDT.start ; GDT Pointer
CODE_SEG equ GDT.codeDescriptor - GDT.start
DATA_SEG equ GDT.dataDescriptor - GDT.start
;; VBE Stuff
; Default width
%ifndef DEF_W
%define DEF_W 0
%endif
; Default height
%ifndef DEF_H
%define DEF_H 0
%endif
; Default bpp
%ifndef DEF_BPP
%define DEF_BPP 0
%endif
; Use defaults
%ifdef DEF_RES
width: dw DEF_W
%else
width: dw 0
%endif
height: dw DEF_H
bpp: db DEF_BPP
offset: dw 0
_segment: dw 0 ; segment is a keyword
mode: dw 0
times (512*2)-($-$$) db 0 ; End Sector 2
;; Sector 2
vbeInfoBlock:
.vbeSigniture: db "VBE2"
.vbeVersion: dw 0x0300 ; BCD Version
.oemStringPtr: dd 0
.capibilities: dd 0
.videoModePtr: dd 0
.totalMemory: dw 0
.oemSoftwareRev: dw 0
.oemVendorNamePtr: dd 0
.oemProductNamePtr: dd 0
.oemProductRevisionPtr: dd 0
.reserved: times 222 db 0
.oemData: times 256 db 0
;; Sector 3
modeInfoBlock:
;; Required by all VBE revisions
.modeAttr: dw 0
.windowAAtrr: db 0
.windowBAttr: db 0
.windowGranularity: dw 0
.windowSize: dw 0
.windowASegment: dw 0
.windowBSegment: dw 0
.windowFunctionPtr: dd 0
.bytesPerScanline: dw 0
;; Required by VBE 1.2+
.xRes: dw 0
.yRes: dw 0
.xCharSize: db 0
.yCharSize: db 0
.planeCount: db 0
.bpp: db 0
.bankCount: db 0
.memoryModel: db 0
.bankSize: db 0
.imagePageCount: db 0
.reserved1: db 1
;; Direct color fields
.redMaskSize: db 0
.redFieldPos: db 0
.greenMaskSize: db 0
.greenFieldPos: db 0
.blueMaskSize: db 0
.blueFieldPos: db 0
.reservedMaskSize: db 0
.reservedFieldPos: db 0
.directColorModeInfo: db 0
;; Required by VBE 2.0+
.physicalBasePtr: dd 0
.reserved2: dd 0
.reserved3: dw 0
;; Required by VBE 3.0+
.linearBytesPerScanline: dw 0
.bankImagePageCount: db 0
.linearImagePageCount: db 0
.linearRedMaskSize: db 0
.linearRedFieldPos: db 0
.linearGreenMaskSize: db 0
.linearGreenFieldPos: db 0
.linearBlueMaskSize: db 0
.linearBlueFieldPos: db 0
.linearReservedMaskSize: db 0
.linearReservedFieldPos: db 0
.maxPixelClock: dd 0
.reserved4: times 190 db 0
times (512*4)-($-$$) db 0