Move bootloader to submodule
This commit is contained in:
parent
7ae998ce3b
commit
5776b0b452
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -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
1
bootloader
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 7639aef32ed5ffd272701d955147b8b50aad53e0
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in a new issue