Move bootloader to submodule

This commit is contained in:
Jeremy Soller 2017-01-05 11:26:32 -07:00
parent 7ae998ce3b
commit 5776b0b452
18 changed files with 4 additions and 1280 deletions

3
.gitmodules vendored
View file

@ -64,3 +64,6 @@
[submodule "drivers"]
path = drivers
url = https://github.com/redox-os/drivers.git
[submodule "bootloader"]
path = bootloader
url = https://github.com/redox-os/bootloader.git

1
bootloader Submodule

@ -0,0 +1 @@
Subproject commit 7639aef32ed5ffd272701d955147b8b50aad53e0

View file

@ -1,17 +0,0 @@
interrupt_vector_table:
b . @ Reset
b .
b . @ SWI instruction
b .
b .
b .
b .
b .
.comm stack, 0x10000 @ Reserve 64k stack in the BSS
_start:
.globl _start
ldr sp, =stack+0x10000 @ Set up the stack
bl kstart @ Jump to the main function
1:
b 1b @ Halt

View file

@ -1,188 +0,0 @@
ORG 0x7C00
SECTION .text
USE16
boot: ; dl comes with disk
; initialize segment registers
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
; initialize stack
mov sp, 0x7C00
; initialize CS
push ax
push word .set_cs
retf
.set_cs:
; save disk number
mov [disk], dl
mov si, name
call print
call print_line
mov bx, (startup_start - boot) / 512
call print_num
call print_line
mov bx, startup_start
call print_num
call print_line
mov eax, (startup_start - boot) / 512
mov bx, startup_start
mov cx, (startup_end - startup_start) / 512
xor dx, dx
call load
mov si, finished
call print
call print_line
jmp startup
; load some sectors from disk to a buffer in memory
; buffer has to be below 1MiB
; IN
; ax: start sector
; bx: offset of buffer
; cx: number of sectors (512 Bytes each)
; dx: segment of buffer
; CLOBBER
; ax, bx, cx, dx, si
; TODO rewrite to (eventually) move larger parts at once
; if that is done increase buffer_size_sectors in startup-common to that (max 0x80000 - startup_end)
load:
cmp cx, 127
jbe .good_size
pusha
mov cx, 127
call load
popa
add ax, 127
add dx, 127 * 512 / 16
sub cx, 127
jmp load
.good_size:
mov [DAPACK.addr], eax
mov [DAPACK.buf], bx
mov [DAPACK.count], cx
mov [DAPACK.seg], dx
call print_dapack
mov dl, [disk]
mov si, DAPACK
mov ah, 0x42
int 0x13
jc error
ret
; store some sectors to disk from a buffer in memory
; buffer has to be below 1MiB
; IN
; ax: start sector
; bx: offset of buffer
; cx: number of sectors (512 Bytes each)
; dx: segment of buffer
; CLOBBER
; ax, bx, cx, dx, si
; TODO rewrite to (eventually) move larger parts at once
; if that is done increase buffer_size_sectors in startup-common to that (max 0x80000 - startup_end)
store:
cmp cx, 127
jbe .good_size
pusha
mov cx, 127
call store
popa
add ax, 127
add dx, 127 * 512 / 16
sub cx, 127
jmp store
.good_size:
mov [DAPACK.addr], eax
mov [DAPACK.buf], bx
mov [DAPACK.count], cx
mov [DAPACK.seg], dx
call print_dapack
mov dl, [disk]
mov si, DAPACK
mov ah, 0x43
int 0x13
jc error
ret
print_dapack:
mov bx, [DAPACK.addr + 2]
call print_num
mov bx, [DAPACK.addr]
call print_num
mov al, '#'
call print_char
mov bx, [DAPACK.count]
call print_num
mov al, ' '
call print_char
mov bx, [DAPACK.seg]
call print_num
mov al, ':'
call print_char
mov bx, [DAPACK.buf]
call print_num
jmp print_line
error:
mov bh, 0
mov bl, ah
call print_num
mov al, ' '
call print_char
mov si, errored
call print
call print_line
.halt:
cli
hlt
jmp .halt
%include "print16.asm"
name: db "Redox Loader - Stage One",0
errored: db "Could not read disk",0
finished: db "Redox Loader - Stage Two",0
disk: db 0
DAPACK:
db 0x10
db 0
.count: dw 0 ; int 13 resets this to # of blocks actually read/written
.buf: dw 0 ; memory buffer destination address (0:7c00)
.seg: dw 0 ; in memory page zero
.addr: dq 0 ; put the lba to read in this spot
times 510-($-$$) db 0
db 0x55
db 0xaa

View file

@ -1,18 +0,0 @@
SECTION .text
USE16
align 512, db 0
config:
.xres: dw 0
.yres: dw 0
times 512 - ($ - config) db 0
save_config:
mov eax, (config - boot) / 512
mov bx, config
mov cx, 1
xor dx, dx
call store
ret

View file

@ -1,46 +0,0 @@
attrib:
.present equ 1 << 7
.ring1 equ 1 << 5
.ring2 equ 1 << 6
.ring3 equ 1 << 5 | 1 << 6
.user equ 1 << 4
;user
.code equ 1 << 3
; code
.conforming equ 1 << 2
.readable equ 1 << 1
; data
.expand_down equ 1 << 2
.writable equ 1 << 1
.accessed equ 1 << 0
;system
; legacy
.tssAvailabe16 equ 0x1
.ldt equ 0x2
.tssBusy16 equ 0x3
.call16 equ 0x4
.task equ 0x5
.interrupt16 equ 0x6
.trap16 equ 0x7
.tssAvailabe32 equ 0x9
.tssBusy32 equ 0xB
.call32 equ 0xC
.interrupt32 equ 0xE
.trap32 equ 0xF
; long mode
.ldt32 equ 0x2
.tssAvailabe64 equ 0x9
.tssBusy64 equ 0xB
.call64 equ 0xC
.interrupt64 equ 0xE
.trap64 equ 0xF
flags:
.granularity equ 1 << 7
.available equ 1 << 4
;user
.default_operand_size equ 1 << 6
; code
.long_mode equ 1 << 5
; data
.reserved equ 1 << 5

View file

@ -1,8 +0,0 @@
struc GDTEntry
.limitl resw 1
.basel resw 1
.basem resb 1
.attribute resb 1
.flags__limith resb 1
.baseh resb 1
endstruc

View file

@ -1,21 +0,0 @@
%include "bootsector.asm"
startup_start:
%ifdef ARCH_i386
%include "startup-i386.asm"
%endif
%ifdef ARCH_x86_64
%include "startup-x86_64.asm"
%endif
align 512, db 0
startup_end:
kernel_file:
incbin "build/kernel/kernel"
align 512, db 0
.end:
.length equ kernel_file.end - kernel_file
.length_sectors equ .length / 512
incbin "build/filesystem.bin"

View file

@ -1,78 +0,0 @@
SECTION .text
USE16
initialize:
.fpu: ;enable fpu
mov eax, cr0
and al, 11110011b
or al, 00100010b
mov cr0, eax
mov eax, cr4
or eax, 0x200
mov cr4, eax
fninit
ret
.sse: ;enable sse
mov eax, cr4
or ax, 0000011000000000b
mov cr4, eax
ret
;PIT Frequency
;If using nanoseconds, to minimize drift, one should find a frequency as close to an integer nanosecond value in wavelength
;Divider Hz Nanoseconds Properties
;2685 444.38795779019242706393 2250286.00003631746492922946 Best For Context Switching
;5370 222.19397889509621353196 4500572.00007263492985856020
;21029 56.73981961418358774390 17624306.99991199998882825455
;23714 50.31549576902532962244 19874592.99994831745375667118
;26399 45.19798729749864262535 22124878.99998463491868476373
;29084 41.02536331545408701233 24375165.00002095238361424615
;31769 37.55804925136663623868 26625451.00005726984854313455
;34454 34.63115071302799868423 28875737.00009358731347639618
;50113 23.80982313305263437963 41999471.99993295237244784676
;52798 22.59899364874932131267 44249757.99996926983737931766
;55483 21.50535599492937776736 46500044.00000558730230583335 Lowest Drift
;58168 20.51268165772704350616 48750330.00004190476724037528
;60853 19.60760630809765610021 51000616.00007822223218031738
.pit:
;initialize the PIT
mov ax, 2685 ;this is the divider for the PIT
out 0x40, al
rol ax, 8
out 0x40, al
;DISABLED ;enable rtc interrupt
;mov al, 0xB
;out 0x70, al
;rol ax, 8
;in al, 0x71
;rol ax, 8
;out 0x70, al
;rol ax, 8
;or al, 0x40
;out 0x71, al
ret
.pic: ;sets up IRQs at int 20-2F
mov al, 0x11
out 0x20, al
out 0xA0, al
mov al, 0x20 ;IRQ0 vector
out 0x21, al
mov al, 0x28 ;IRQ8 vector
out 0xA1, al
mov al, 4
out 0x21, al
mov al, 2
out 0xA1, al
mov al, 1
out 0x21, al
out 0xA1, al
xor al, al ;no IRQ masks
out 0x21, al
out 0xA1, al
mov al, 0x20 ;reset PIC's
out 0xA0, al
out 0x20, al
ret

View file

@ -1,19 +0,0 @@
%include "bootsector.asm"
startup_start:
%ifdef ARCH_i386
%include "startup-i386.asm"
%endif
%ifdef ARCH_x86_64
%include "startup-x86_64.asm"
%endif
align 512, db 0
startup_end:
kernel_file:
incbin "build/kernel/kernel_live"
align 512, db 0
.end:
.length equ kernel_file.end - kernel_file
.length_sectors equ .length / 512

View file

@ -1,32 +0,0 @@
SECTION .text
USE16
;Generate a memory map at 0x500 to 0x5000 (available memory not used for kernel or bootloader)
memory_map:
.start equ 0x0500
.end equ 0x5000
.length equ .end - .start
xor eax, eax
mov di, .start
mov ecx, .length / 4 ; moving 4 Bytes at once
cld
rep stosd
mov di, .start
mov edx, 0x534D4150
xor ebx, ebx
.lp:
mov eax, 0xE820
mov ecx, 24
int 0x15
jc .done ; Error or finished
cmp ebx, 0
je .done ; Finished
add di, 24
cmp di, .end
jb .lp ; Still have buffer space
.done:
ret

View file

@ -1,65 +0,0 @@
SECTION .text
USE16
; provide function for printing in x86 real mode
; print a string and a newline
; IN
; si: points at zero-terminated String
; CLOBBER
; ax
print_line:
mov al, 13
call print_char
mov al, 10
jmp print_char
; print a string
; IN
; si: points at zero-terminated String
; CLOBBER
; ax
print:
cld
.loop:
lodsb
test al, al
jz .done
call print_char
jmp .loop
.done:
ret
; print a character
; IN
; al: character to print
; CLOBBER
; ah
print_char:
mov ah, 0x0e
int 0x10
ret
; print a number in hex
; IN
; bx: the number
; CLOBBER
; cx, ax
print_num:
mov cx, 4
.lp:
mov al, bh
shr al, 4
cmp al, 0xA
jb .below_0xA
add al, 'A' - 0xA - '0'
.below_0xA:
add al, '0'
call print_char
shl bx, 4
loop .lp
ret

View file

@ -1,110 +0,0 @@
SECTION .text
USE16
startup:
; enable A20-Line via IO-Port 92, might not work on all motherboards
in al, 0x92
or al, 2
out 0x92, al
; loading kernel to 1MiB
; move part of kernel to startup_end via bootsector#load and then copy it up
; repeat until all of the kernel is loaded
; buffersize in multiple of sectors (512 Bytes)
; min 1
; max (0x70000 - startup_end) / 512
buffer_size_sectors equ 127
; buffer size in Bytes
buffer_size_bytes equ buffer_size_sectors * 512
kernel_base equ 0x100000
; how often do we need to call load and move memory
mov ecx, kernel_file.length_sectors / buffer_size_sectors
mov eax, (kernel_file - boot) / 512
mov edi, kernel_base
cld
.lp:
; saving counter
push cx
; populating buffer
mov cx, buffer_size_sectors
mov bx, kernel_file
mov dx, 0x0
push edi
push eax
call load
; moving buffer
call unreal
pop eax
pop edi
mov esi, kernel_file
mov ecx, buffer_size_bytes / 4
a32 rep movsd
; preparing next iteration
add eax, buffer_size_sectors
pop cx
loop .lp
; load the part of the kernel that does not fill the buffer completely
mov cx, kernel_file.length_sectors % buffer_size_sectors
test cx, cx
jz finished_loading ; if cx = 0 => skip
mov bx, kernel_file
mov dx, 0x0
call load
; moving remnants of kernel
call unreal
mov esi, kernel_file
mov ecx, (kernel_file.length_sectors % buffer_size_bytes) / 4
a32 rep movsd
finished_loading:
call memory_map
call vesa
mov si, init_fpu_msg
call printrm
call initialize.fpu
mov si, init_sse_msg
call printrm
call initialize.sse
mov si, init_pit_msg
call printrm
call initialize.pit
mov si, init_pic_msg
call printrm
call initialize.pic
mov si, startup_arch_msg
call printrm
jmp startup_arch
%include "config.asm"
%include "descriptor_flags.inc"
%include "gdt_entry.inc"
%include "unreal.asm"
%include "memory_map.asm"
%include "vesa.asm"
%include "initialize.asm"
init_fpu_msg: db "Init FPU",13,10,0
init_sse_msg: db "Init SSE",13,10,0
init_pit_msg: db "Init PIT",13,10,0
init_pic_msg: db "Init PIC",13,10,0
startup_arch_msg: db "Startup Arch",13,10,0

View file

@ -1,148 +0,0 @@
%include "startup-common.asm"
startup_arch:
; load protected mode GDT and IDT
cli
lgdt [gdtr]
lidt [idtr]
; set protected mode bit of cr0
mov eax, cr0
or eax, 1
mov cr0, eax
; far jump to load CS with 32 bit segment
jmp gdt.kernel_code:protected_mode
USE32
protected_mode:
; load all the other segments with 32 bit data segments
mov eax, gdt.kernel_data
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov esp, 0x800000 - 128
mov eax, gdt.tss
ltr ax
;rust init
mov eax, [kernel_base + 0x18]
mov [interrupts.handler], eax
mov eax, gdtr
mov ebx, idtr
mov ecx, tss
int 255
.lp:
sti
hlt
jmp .lp
gdtr:
dw gdt.end + 1 ; size
dd gdt ; offset
gdt:
.null equ $ - gdt
dq 0
.kernel_code equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0xFFFF
at GDTEntry.basel, dw 0
at GDTEntry.basem, db 0
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.code | attrib.readable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.kernel_data equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0xFFFF
at GDTEntry.basel, dw 0
at GDTEntry.basem, db 0
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.user_code equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0xFFFF
at GDTEntry.basel, dw 0
at GDTEntry.basem, db 0
at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.user | attrib.code | attrib.readable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.user_data equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0xFFFF
at GDTEntry.basel, dw 0
at GDTEntry.basem, db 0
at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.user | attrib.writable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.user_tls equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0xFFFF
at GDTEntry.basel, dw 0
at GDTEntry.basem, db 0
at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.user | attrib.writable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0
iend
.tss equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw (tss.end - tss) & 0xFFFF
at GDTEntry.basel, dw (tss-$$+0x7C00) & 0xFFFF
at GDTEntry.basem, db ((tss-$$+0x7C00) >> 16) & 0xFF
at GDTEntry.attribute, db attrib.present | attrib.ring3 | attrib.tssAvailabe32
at GDTEntry.flags__limith, db ((tss.end - tss) >> 16) & 0xF
at GDTEntry.baseh, db ((tss-$$+0x7C00) >> 24) & 0xFF
iend
.end equ $ - gdt
struc TSS
.prev_tss resd 1 ;The previous TSS - if we used hardware task switching this would form a linked list.
.esp0 resd 1 ;The stack pointer to load when we change to kernel mode.
.ss0 resd 1 ;The stack segment to load when we change to kernel mode.
.esp1 resd 1 ;everything below here is unused now..
.ss1 resd 1
.esp2 resd 1
.ss2 resd 1
.cr3 resd 1
.eip resd 1
.eflags resd 1
.eax resd 1
.ecx resd 1
.edx resd 1
.ebx resd 1
.esp resd 1
.ebp resd 1
.esi resd 1
.edi resd 1
.es resd 1
.cs resd 1
.ss resd 1
.ds resd 1
.fs resd 1
.gs resd 1
.ldt resd 1
.trap resw 1
.iomap_base resw 1
endstruc
tss:
istruc TSS
at TSS.esp0, dd 0x800000 - 128
at TSS.ss0, dd gdt.kernel_data
at TSS.iomap_base, dw 0xFFFF
iend
.end:

View file

@ -1,179 +0,0 @@
trampoline:
.ready: dq 0
.cpu_id: dq 0
.page_table: dq 0
.stack_start: dq 0
.stack_end: dq 0
.code: dq 0
times 512 - ($ - trampoline) db 0
startup_ap:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
; initialize stack
mov sp, 0x7C00
call initialize.fpu
call initialize.sse
;cr3 holds pointer to PML4
mov edi, 0x70000
mov cr3, edi
;enable FXSAVE/FXRSTOR, Page Global, Page Address Extension, and Page Size Extension
mov eax, cr4
or eax, 1 << 9 | 1 << 7 | 1 << 5 | 1 << 4
mov cr4, eax
; load protected mode GDT
lgdt [gdtr]
mov ecx, 0xC0000080 ; Read from the EFER MSR.
rdmsr
or eax, 1 << 11 | 1 << 8 ; Set the Long-Mode-Enable and NXE bit.
wrmsr
;enabling paging and protection simultaneously
mov ebx, cr0
or ebx, 1 << 31 | 1 << 16 | 1 ;Bit 31: Paging, Bit 16: write protect kernel, Bit 0: Protected Mode
mov cr0, ebx
; far jump to enable Long Mode and load CS with 64 bit segment
jmp gdt.kernel_code:long_mode_ap
%include "startup-common.asm"
startup_arch:
cli
; setting up Page Tables
; Identity Mapping first GB
mov ax, 0x7000
mov es, ax
xor edi, edi
xor eax, eax
mov ecx, 6 * 4096 / 4 ;PML4, PDP, 4 PD / moves 4 Bytes at once
cld
rep stosd
xor edi, edi
;Link first PML4 and second to last PML4 to PDP
mov DWORD [es:edi], 0x71000 | 1 << 1 | 1
mov DWORD [es:edi + 510*8], 0x71000 | 1 << 1 | 1
add edi, 0x1000
;Link last PML4 to PML4
mov DWORD [es:edi - 8], 0x70000 | 1 << 1 | 1
;Link first four PDP to PD
mov DWORD [es:edi], 0x72000 | 1 << 1 | 1
mov DWORD [es:edi + 8], 0x73000 | 1 << 1 | 1
mov DWORD [es:edi + 16], 0x74000 | 1 << 1 | 1
mov DWORD [es:edi + 24], 0x75000 | 1 << 1 | 1
add edi, 0x1000
;Link all PD's (512 per PDP, 2MB each)y
mov ebx, 1 << 7 | 1 << 1 | 1
mov ecx, 4*512
.setpd:
mov [es:edi], ebx
add ebx, 0x200000
add edi, 8
loop .setpd
xor ax, ax
mov es, ax
;cr3 holds pointer to PML4
mov edi, 0x70000
mov cr3, edi
;enable FXSAVE/FXRSTOR, Page Global, Page Address Extension, and Page Size Extension
mov eax, cr4
or eax, 1 << 9 | 1 << 7 | 1 << 5 | 1 << 4
mov cr4, eax
; load protected mode GDT
lgdt [gdtr]
mov ecx, 0xC0000080 ; Read from the EFER MSR.
rdmsr
or eax, 1 << 11 | 1 << 8 ; Set the Long-Mode-Enable and NXE bit.
wrmsr
;enabling paging and protection simultaneously
mov ebx, cr0
or ebx, 1 << 31 | 1 << 16 | 1 ;Bit 31: Paging, Bit 16: write protect kernel, Bit 0: Protected Mode
mov cr0, ebx
; far jump to enable Long Mode and load CS with 64 bit segment
jmp gdt.kernel_code:long_mode
USE64
long_mode:
; load all the other segments with 64 bit data segments
mov rax, gdt.kernel_data
mov ds, rax
mov es, rax
mov fs, rax
mov gs, rax
mov ss, rax
mov rsp, 0xFFFFFF000009F000
;rust init
mov rax, [kernel_base + 0x18]
jmp rax
long_mode_ap:
mov rax, gdt.kernel_data
mov ds, rax
mov es, rax
mov fs, rax
mov gs, rax
mov ss, rax
mov rdi, [trampoline.cpu_id]
mov rsi, [trampoline.page_table]
mov rdx, [trampoline.stack_start]
mov rcx, [trampoline.stack_end]
lea rsp, [rcx - 256]
mov rax, [trampoline.code]
mov qword [trampoline.ready], 1
jmp rax
gdtr:
dw gdt.end + 1 ; size
dq gdt ; offset
gdt:
.null equ $ - gdt
dq 0
.kernel_code equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0
at GDTEntry.basel, dw 0
at GDTEntry.basem, db 0
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.code
at GDTEntry.flags__limith, db flags.long_mode
at GDTEntry.baseh, db 0
iend
.kernel_data equ $ - gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0
at GDTEntry.basel, dw 0
at GDTEntry.basem, db 0
; AMD System Programming Manual states that the writeable bit is ignored in long mode, but ss can not be set to this descriptor without it
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable
at GDTEntry.flags__limith, db 0
at GDTEntry.baseh, db 0
iend
.end equ $ - gdt

View file

@ -1,54 +0,0 @@
SECTION .text
USE16
; switch to unreal mode; ds and es can address up to 4GiB
unreal:
cli
lgdt [unreal_gdtr]
push es
push ds
mov eax, cr0 ; switch to pmode by
or al,1 ; set pmode bit
mov cr0, eax
jmp $+2
; http://wiki.osdev.org/Babystep7
; When this register given a "selector", a "segment descriptor cache register"
; is filled with the descriptor values, including the size (or limit). After
; the switch back to real mode, these values are not modified, regardless of
; what value is in the 16-bit segment register. So the 64k limit is no longer
; valid and 32-bit offsets can be used with the real-mode addressing rules
mov bx, unreal_gdt.data
mov es, bx
mov ds, bx
and al,0xFE ; back to realmode
mov cr0, eax ; by toggling bit again
pop ds
pop es
sti
ret
unreal_gdtr:
dw unreal_gdt.end + 1 ; size
dd unreal_gdt ; offset
unreal_gdt:
.null equ $ - unreal_gdt
dq 0
.data equ $ - unreal_gdt
istruc GDTEntry
at GDTEntry.limitl, dw 0xFFFF
at GDTEntry.basel, dw 0x0
at GDTEntry.basem, db 0x0
at GDTEntry.attribute, db attrib.present | attrib.user | attrib.writable
at GDTEntry.flags__limith, db 0xFF | flags.granularity | flags.default_operand_size
at GDTEntry.baseh, db 0x0
iend
.end equ $ - unreal_gdt

View file

@ -1,207 +0,0 @@
%include "vesa.inc"
SECTION .text
USE16
vesa:
.getcardinfo:
mov ax, 0x4F00
mov di, VBECardInfo
int 0x10
cmp ax, 0x4F
je .findmode
mov eax, 1
ret
.resetlist:
;if needed, reset mins/maxes/stuff
xor cx, cx
mov [.minx], cx
mov [.miny], cx
mov [config.xres], cx
mov [config.yres], cx
.findmode:
mov si, [VBECardInfo.videomodeptr]
mov ax, [VBECardInfo.videomodeptr+2]
mov fs, ax
sub si, 2
.searchmodes:
add si, 2
mov cx, [fs:si]
cmp cx, 0xFFFF
jne .getmodeinfo
cmp word [.goodmode], 0
je .resetlist
jmp .findmode
.getmodeinfo:
push esi
mov [.currentmode], cx
mov ax, 0x4F01
mov di, VBEModeInfo
int 0x10
pop esi
cmp ax, 0x4F
je .foundmode
mov eax, 1
ret
.foundmode:
;check minimum values, really not minimums from an OS perspective but ugly for users
cmp byte [VBEModeInfo.bitsperpixel], 32
jb .searchmodes
.testx:
mov cx, [VBEModeInfo.xresolution]
cmp word [config.xres], 0
je .notrequiredx
cmp cx, [config.xres]
je .testy
jmp .searchmodes
.notrequiredx:
cmp cx, [.minx]
jb .searchmodes
.testy:
mov cx, [VBEModeInfo.yresolution]
cmp word [config.yres], 0
je .notrequiredy
cmp cx, [config.yres]
jne .searchmodes ;as if there weren't enough warnings, USE WITH CAUTION
cmp word [config.xres], 0
jnz .setmode
jmp .testgood
.notrequiredy:
cmp cx, [.miny]
jb .searchmodes
.testgood:
mov cx, [.currentmode]
mov [.goodmode], cx
push esi
; call decshowrm
; mov al, ':'
; call charrm
mov cx, [VBEModeInfo.xresolution]
call decshowrm
mov al, 'x'
call charrm
mov cx, [VBEModeInfo.yresolution]
call decshowrm
mov al, '@'
call charrm
xor ch, ch
mov cl, [VBEModeInfo.bitsperpixel]
call decshowrm
mov si, .modeok
call printrm
xor ax, ax
int 0x16
pop esi
cmp al, 'y'
je .setmode
cmp al, 's'
je .savemode
jmp .searchmodes
.savemode:
mov cx, [VBEModeInfo.xresolution]
mov [config.xres], cx
mov cx, [VBEModeInfo.yresolution]
mov [config.yres], cx
call save_config
.setmode:
mov bx, [.currentmode]
cmp bx, 0
je .nomode
or bx, 0x4000
mov ax, 0x4F02
int 0x10
.nomode:
cmp ax, 0x4F
je .returngood
mov eax, 1
ret
.returngood:
xor eax, eax
ret
.minx dw 640
.miny dw 480
.modeok db ": Is this OK? (s)ave/(y)es/(n)o",10,13,0
.goodmode dw 0
.currentmode dw 0
;useful functions
decshowrm:
mov si, .number
.clear:
mov al, "0"
mov [si], al
inc si
cmp si, .numberend
jb .clear
dec si
call convertrm
mov si, .number
.lp:
lodsb
cmp si, .numberend
jae .end
cmp al, "0"
jbe .lp
.end:
dec si
call printrm
ret
.number times 7 db 0
.numberend db 0
convertrm:
dec si
mov bx, si ;place to convert into must be in si, number to convert must be in cx
.cnvrt:
mov si, bx
sub si, 4
.ten4: inc si
cmp cx, 10000
jb .ten3
sub cx, 10000
inc byte [si]
jmp .cnvrt
.ten3: inc si
cmp cx, 1000
jb .ten2
sub cx, 1000
inc byte [si]
jmp .cnvrt
.ten2: inc si
cmp cx, 100
jb .ten1
sub cx, 100
inc byte [si]
jmp .cnvrt
.ten1: inc si
cmp cx, 10
jb .ten0
sub cx, 10
inc byte [si]
jmp .cnvrt
.ten0: inc si
cmp cx, 1
jb .return
sub cx, 1
inc byte [si]
jmp .cnvrt
.return:
ret
printrm:
mov al, [si]
test al, al
jz .return
call charrm
inc si
jmp printrm
.return:
ret
charrm: ;char must be in al
mov bx, 7
mov ah, 0xE
int 10h
ret

View file

@ -1,90 +0,0 @@
ABSOLUTE 0x5000
VBECardInfo:
.signature resb 4
.version resw 1
.oemstring resd 1
.capabilities resd 1
.videomodeptr resd 1
.totalmemory resw 1
.oemsoftwarerev resw 1
.oemvendornameptr resd 1
.oemproductnameptr resd 1
.oemproductrevptr resd 1
.reserved resb 222
.oemdata resb 256
ABSOLUTE 0x5200
VBEModeInfo:
.attributes resw 1
.winA resb 1
.winB resb 1
.granularity resw 1
.winsize resw 1
.segmentA resw 1
.segmentB resw 1
.winfuncptr resd 1
.bytesperscanline resw 1
.xresolution resw 1
.yresolution resw 1
.xcharsize resb 1
.ycharsize resb 1
.numberofplanes resb 1
.bitsperpixel resb 1
.numberofbanks resb 1
.memorymodel resb 1
.banksize resb 1
.numberofimagepages resb 1
.unused resb 1
.redmasksize resb 1
.redfieldposition resb 1
.greenmasksize resb 1
.greenfieldposition resb 1
.bluemasksize resb 1
.bluefieldposition resb 1
.rsvdmasksize resb 1
.rsvdfieldposition resb 1
.directcolormodeinfo resb 1
.physbaseptr resd 1
.offscreenmemoryoffset resd 1
.offscreenmemsize resw 1
.reserved resb 206
VBE.ModeAttributes:
.available equ 1 << 0
.bios equ 1 << 2
.color equ 1 << 3
.graphics equ 1 << 4
.vgacompatible equ 1 << 5
.notbankable equ 1 << 6
.linearframebuffer equ 1 << 7
ABSOLUTE 0x5400
VBEEDID:
.header resb 8
.manufacturer resw 1
.productid resw 1
.serial resd 1
.manufactureweek resb 1
.manufactureyear resb 1
.version resb 1
.revision resb 1
.input resb 1
.horizontalsize resb 1
.verticalsize resb 1
.gamma resb 1
.displaytype resb 1
.chromaticity resb 10
.timingI resb 1
.timingII resb 1
.timingreserved resb 1
.standardtiming: resw 8 ;format: db (horizontal-248)/8, aspectratio | verticalfrequency - 60
.aspect.16.10 equ 0 ;mul horizontal by 10, shr 4 to get vertical resolution
.aspect.4.3 equ 1 << 6 ;mul horizontal by 3, shr 2 to get vertical resolution
.aspect.5.4 equ 2 << 6 ;shl horizontal by 2, div by 5 to get vertical resolution
.aspect.16.9 equ 3 << 6 ;mul horizontal by 9, shr by 4 to get vertical resolution
.descriptorblock1 resb 18
.descriptorblock2 resb 18
.descriptorblock3 resb 18
.descriptorblock4 resb 18
.extensionflag resb 1
.checksum resb 1