Added bios loader
parent
b2653f5f55
commit
ff9dae24ff
|
@ -0,0 +1,31 @@
|
||||||
|
sectalign off
|
||||||
|
|
||||||
|
; stage 1 is sector 0, loaded at 0x7C00
|
||||||
|
%include "stage1.asm"
|
||||||
|
|
||||||
|
; GPT area from sector 1 to 33, loaded at 0x7E00
|
||||||
|
times (33*512) db 0
|
||||||
|
|
||||||
|
; stage 2, loaded at 0xC000
|
||||||
|
stage2:
|
||||||
|
%include "stage2.asm"
|
||||||
|
align 512, db 0
|
||||||
|
stage2.end:
|
||||||
|
|
||||||
|
; the maximum size of stage2 is 4 KiB
|
||||||
|
times (4*1024)-($-stage2) db 0
|
||||||
|
|
||||||
|
; ISO compatibility, uses up space until 0x12400
|
||||||
|
%include "iso.asm"
|
||||||
|
|
||||||
|
times 3072 db 0 ; Pad to 0x13000
|
||||||
|
|
||||||
|
; stage3, loaded at 0x13000
|
||||||
|
stage3:
|
||||||
|
; %defstr STAGE3_STR %[STAGE3]
|
||||||
|
; incbin STAGE3_STR
|
||||||
|
; align 512, db 0
|
||||||
|
.end:
|
||||||
|
|
||||||
|
; the maximum size of the boot loader portion is 384 KiB
|
||||||
|
times (384*1024)-($-$$) db 0
|
|
@ -0,0 +1,176 @@
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
|
||||||
|
cpuid_required_features:
|
||||||
|
.edx equ cpuid_edx.fpu | cpuid_edx.pse | cpuid_edx.pge | cpuid_edx.fxsr
|
||||||
|
.ecx equ 0
|
||||||
|
|
||||||
|
cpuid_check:
|
||||||
|
; If bit 21 of EFLAGS can be changed, then CPUID is supported
|
||||||
|
pushfd ;Save EFLAGS
|
||||||
|
pushfd ;Store EFLAGS
|
||||||
|
xor dword [esp],0x00200000 ;Invert the ID bit in stored EFLAGS
|
||||||
|
popfd ;Load stored EFLAGS (with ID bit inverted)
|
||||||
|
pushfd ;Store EFLAGS again (ID bit may or may not be inverted)
|
||||||
|
pop eax ;eax = modified EFLAGS (ID bit may or may not be inverted)
|
||||||
|
xor eax,[esp] ;eax = whichever bits were changed
|
||||||
|
popfd ;Restore original EFLAGS
|
||||||
|
test eax,0x00200000 ;eax = zero if ID bit can't be changed, else non-zero
|
||||||
|
jz .no_cpuid
|
||||||
|
|
||||||
|
mov eax, 1
|
||||||
|
cpuid
|
||||||
|
|
||||||
|
and edx, cpuid_required_features.edx
|
||||||
|
cmp edx, cpuid_required_features.edx
|
||||||
|
jne .error
|
||||||
|
|
||||||
|
and ecx, cpuid_required_features.ecx
|
||||||
|
cmp ecx, cpuid_required_features.ecx
|
||||||
|
jne .error
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.no_cpuid:
|
||||||
|
mov si, .msg_cpuid
|
||||||
|
call print
|
||||||
|
|
||||||
|
mov si, .msg_line
|
||||||
|
call print
|
||||||
|
|
||||||
|
jmp .halt
|
||||||
|
|
||||||
|
.error:
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
|
||||||
|
mov si, .msg_features
|
||||||
|
call print
|
||||||
|
|
||||||
|
mov si, .msg_line
|
||||||
|
call print
|
||||||
|
|
||||||
|
mov si, .msg_edx
|
||||||
|
call print
|
||||||
|
|
||||||
|
pop ebx
|
||||||
|
push ebx
|
||||||
|
shr ebx, 16
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
pop ebx
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov si, .msg_must_contain
|
||||||
|
call print
|
||||||
|
|
||||||
|
mov ebx, cpuid_required_features.edx
|
||||||
|
shr ebx, 16
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov ebx, cpuid_required_features.edx
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov si, .msg_line
|
||||||
|
call print
|
||||||
|
|
||||||
|
mov si, .msg_ecx
|
||||||
|
call print
|
||||||
|
|
||||||
|
pop ebx
|
||||||
|
push ebx
|
||||||
|
shr ebx, 16
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
pop ebx
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov si, .msg_must_contain
|
||||||
|
call print
|
||||||
|
|
||||||
|
mov ebx, cpuid_required_features.ecx
|
||||||
|
shr ebx, 16
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov ebx, cpuid_required_features.ecx
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov si, .msg_line
|
||||||
|
call print
|
||||||
|
|
||||||
|
.halt:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp .halt
|
||||||
|
|
||||||
|
.msg_cpuid: db "CPUID not supported",0
|
||||||
|
.msg_features: db "Required CPU features are not present",0
|
||||||
|
.msg_line: db 13,10,0
|
||||||
|
.msg_edx: db "EDX ",0
|
||||||
|
.msg_ecx: db "ECX ",0
|
||||||
|
.msg_must_contain: db " must contain ",0
|
||||||
|
|
||||||
|
cpuid_edx:
|
||||||
|
.fpu equ 1 << 0
|
||||||
|
.vme equ 1 << 1
|
||||||
|
.de equ 1 << 2
|
||||||
|
.pse equ 1 << 3
|
||||||
|
.tsc equ 1 << 4
|
||||||
|
.msr equ 1 << 5
|
||||||
|
.pae equ 1 << 6
|
||||||
|
.mce equ 1 << 7
|
||||||
|
.cx8 equ 1 << 8
|
||||||
|
.apic equ 1 << 9
|
||||||
|
.sep equ 1 << 11
|
||||||
|
.mtrr equ 1 << 12
|
||||||
|
.pge equ 1 << 13
|
||||||
|
.mca equ 1 << 14
|
||||||
|
.cmov equ 1 << 15
|
||||||
|
.pat equ 1 << 16
|
||||||
|
.pse_36 equ 1 << 17
|
||||||
|
.psn equ 1 << 18
|
||||||
|
.clfsh equ 1 << 19
|
||||||
|
.ds equ 1 << 21
|
||||||
|
.acpi equ 1 << 22
|
||||||
|
.mmx equ 1 << 23
|
||||||
|
.fxsr equ 1 << 24
|
||||||
|
.sse equ 1 << 25
|
||||||
|
.sse2 equ 1 << 26
|
||||||
|
.ss equ 1 << 27
|
||||||
|
.htt equ 1 << 28
|
||||||
|
.tm equ 1 << 29
|
||||||
|
.ia64 equ 1 << 30
|
||||||
|
.pbe equ 1 << 31
|
||||||
|
|
||||||
|
cpuid_ecx:
|
||||||
|
.sse3 equ 1 << 0
|
||||||
|
.pclmulqdq equ 1 << 1
|
||||||
|
.dtes64 equ 1 << 2
|
||||||
|
.monitor equ 1 << 3
|
||||||
|
.ds_cpl equ 1 << 4
|
||||||
|
.vmx equ 1 << 5
|
||||||
|
.smx equ 1 << 6
|
||||||
|
.est equ 1 << 7
|
||||||
|
.tm2 equ 1 << 8
|
||||||
|
.ssse3 equ 1 << 9
|
||||||
|
.cnxt_id equ 1 << 10
|
||||||
|
.sdbg equ 1 << 11
|
||||||
|
.fma equ 1 << 12
|
||||||
|
.cmpxchg16b equ 1 << 13
|
||||||
|
.xtpr equ 1 << 14
|
||||||
|
.pdcm equ 1 << 15
|
||||||
|
.pcid equ 1 << 17
|
||||||
|
.dca equ 1 << 18
|
||||||
|
.sse4_1 equ 1 << 19
|
||||||
|
.sse4_2 equ 1 << 20
|
||||||
|
.x2apic equ 1 << 21
|
||||||
|
.movbe equ 1 << 22
|
||||||
|
.popcnt equ 1 << 23
|
||||||
|
.tsc_deadline equ 1 << 24
|
||||||
|
.aes equ 1 << 25
|
||||||
|
.xsave equ 1 << 26
|
||||||
|
.osxsave equ 1 << 27
|
||||||
|
.avx equ 1 << 28
|
||||||
|
.f16c equ 1 << 29
|
||||||
|
.rdrand equ 1 << 30
|
||||||
|
.hypervisor equ 1 << 31
|
|
@ -0,0 +1,128 @@
|
||||||
|
SECTION .text ; cannot use .data
|
||||||
|
|
||||||
|
struc GDTEntry
|
||||||
|
.limitl resw 1
|
||||||
|
.basel resw 1
|
||||||
|
.basem resb 1
|
||||||
|
.attribute resb 1
|
||||||
|
.flags__limith resb 1
|
||||||
|
.baseh resb 1
|
||||||
|
endstruc
|
||||||
|
|
||||||
|
gdt_attr:
|
||||||
|
.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
|
||||||
|
|
||||||
|
gdt_flag:
|
||||||
|
.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
|
||||||
|
|
||||||
|
gdtr:
|
||||||
|
dw gdt.end + 1 ; size
|
||||||
|
dq gdt ; offset
|
||||||
|
|
||||||
|
gdt:
|
||||||
|
.null equ $ - gdt
|
||||||
|
dq 0
|
||||||
|
|
||||||
|
.lm64_code equ $ - gdt
|
||||||
|
istruc GDTEntry
|
||||||
|
at GDTEntry.limitl, dw 0
|
||||||
|
at GDTEntry.basel, dw 0
|
||||||
|
at GDTEntry.basem, db 0
|
||||||
|
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.code
|
||||||
|
at GDTEntry.flags__limith, db gdt_flag.long_mode
|
||||||
|
at GDTEntry.baseh, db 0
|
||||||
|
iend
|
||||||
|
|
||||||
|
.lm64_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 gdt_attr.present | gdt_attr.user | gdt_attr.writable
|
||||||
|
at GDTEntry.flags__limith, db 0
|
||||||
|
at GDTEntry.baseh, db 0
|
||||||
|
iend
|
||||||
|
|
||||||
|
.pm32_code equ $ - gdt
|
||||||
|
istruc GDTEntry
|
||||||
|
at GDTEntry.limitl, dw 0xFFFF
|
||||||
|
at GDTEntry.basel, dw 0
|
||||||
|
at GDTEntry.basem, db 0
|
||||||
|
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.code | gdt_attr.readable
|
||||||
|
at GDTEntry.flags__limith, db 0xF | gdt_flag.granularity | gdt_flag.default_operand_size
|
||||||
|
at GDTEntry.baseh, db 0
|
||||||
|
iend
|
||||||
|
|
||||||
|
.pm32_data equ $ - gdt
|
||||||
|
istruc GDTEntry
|
||||||
|
at GDTEntry.limitl, dw 0xFFFF
|
||||||
|
at GDTEntry.basel, dw 0
|
||||||
|
at GDTEntry.basem, db 0
|
||||||
|
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.writable
|
||||||
|
at GDTEntry.flags__limith, db 0xF | gdt_flag.granularity | gdt_flag.default_operand_size
|
||||||
|
at GDTEntry.baseh, db 0
|
||||||
|
iend
|
||||||
|
|
||||||
|
.pm16_code equ $ - gdt
|
||||||
|
istruc GDTEntry
|
||||||
|
at GDTEntry.limitl, dw 0xFFFF
|
||||||
|
at GDTEntry.basel, dw 0
|
||||||
|
at GDTEntry.basem, db 0
|
||||||
|
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.code | gdt_attr.readable
|
||||||
|
at GDTEntry.flags__limith, db 0xF
|
||||||
|
at GDTEntry.baseh, db 0
|
||||||
|
iend
|
||||||
|
|
||||||
|
.pm16_data equ $ - gdt
|
||||||
|
istruc GDTEntry
|
||||||
|
at GDTEntry.limitl, dw 0xFFFF
|
||||||
|
at GDTEntry.basel, dw 0
|
||||||
|
at GDTEntry.basem, db 0
|
||||||
|
at GDTEntry.attribute, db gdt_attr.present | gdt_attr.user | gdt_attr.writable
|
||||||
|
at GDTEntry.flags__limith, db 0xF
|
||||||
|
at GDTEntry.baseh, db 0
|
||||||
|
iend
|
||||||
|
|
||||||
|
.end equ $ - gdt
|
|
@ -0,0 +1,161 @@
|
||||||
|
; Simple ISO emulation with el torito
|
||||||
|
|
||||||
|
; Fill until CD sector 0x10
|
||||||
|
times (0x10*2048)-($-$$) db 0
|
||||||
|
|
||||||
|
; Volume record
|
||||||
|
;TODO: fill in more fields
|
||||||
|
iso_volume_record:
|
||||||
|
db 1 ; Type volume record
|
||||||
|
db "CD001" ; Identifier
|
||||||
|
db 1 ; Version
|
||||||
|
db 0 ; Unused
|
||||||
|
times 32 db ' ' ; System identifier
|
||||||
|
.volume_id: ; Volume identifier
|
||||||
|
db 'Redox OS'
|
||||||
|
times 32-($-.volume_id) db ' '
|
||||||
|
times 8 db 0 ; Unused
|
||||||
|
db 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15 ; Volume space size (0x15)
|
||||||
|
times 32 db 0 ; Unused
|
||||||
|
db 0x01, 0x00, 0x00, 0x01 ; Volume set size
|
||||||
|
db 0x01, 0x00, 0x00, 0x01 ; Volume sequence number
|
||||||
|
db 0x00, 0x08, 0x08, 0x00 ; Logical block size in little and big endian
|
||||||
|
|
||||||
|
times 156-($-iso_volume_record) db 0
|
||||||
|
|
||||||
|
; Root directory entry
|
||||||
|
.root_directory:
|
||||||
|
db 0x22 ; Length of entry
|
||||||
|
db 0x00 ; Length of extended attributes
|
||||||
|
db 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 ; Location of extent (0x14)
|
||||||
|
db 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 ; Size of extent
|
||||||
|
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Recording time
|
||||||
|
db 0x02 ; File flags
|
||||||
|
db 0x00 ; Interleaved file unit size
|
||||||
|
db 0x00 ; Interleaved gap size
|
||||||
|
db 0x01, 0x00, 0x00, 0x01 ; Volume sequence number
|
||||||
|
db 0x01 ; Length of file identifier
|
||||||
|
db 0x00 ; File identifier
|
||||||
|
|
||||||
|
times 128 db ' ' ; Volume set identifier
|
||||||
|
times 128 db ' ' ; Publisher identifier
|
||||||
|
times 128 db ' ' ; Data preparer identifier
|
||||||
|
times 128 db ' ' ; Application identifier
|
||||||
|
times 37 db ' ' ; Copyright file ID
|
||||||
|
times 37 db ' ' ; Abstract file ID
|
||||||
|
times 37 db ' ' ; Bibliographic file ID
|
||||||
|
|
||||||
|
times 881-($-iso_volume_record) db 0
|
||||||
|
|
||||||
|
db 1 ; File structure version
|
||||||
|
|
||||||
|
; Fill until CD sector 0x11
|
||||||
|
times (0x11*2048)-($-$$) db 0
|
||||||
|
|
||||||
|
; Boot record
|
||||||
|
iso_boot_record:
|
||||||
|
db 0 ; Type boot record
|
||||||
|
db "CD001" ; Identifier
|
||||||
|
db 1 ; Version
|
||||||
|
db "EL TORITO SPECIFICATION" ; Boot system identifier
|
||||||
|
times 0x47-($ - iso_boot_record) db 0 ; Padding
|
||||||
|
dd 0x13 ; Sector of boot catalog
|
||||||
|
|
||||||
|
; Fill until CD sector 0x12
|
||||||
|
times (0x12*2048)-($-$$) db 0
|
||||||
|
|
||||||
|
; Terminator
|
||||||
|
iso_terminator:
|
||||||
|
db 0xFF ; Type terminator
|
||||||
|
db "CD001" ; Identifier
|
||||||
|
db 1 ; Version
|
||||||
|
|
||||||
|
; Fill until CD sector 0x13
|
||||||
|
times (0x13*2048)-($-$$) db 0
|
||||||
|
|
||||||
|
; Boot catalog
|
||||||
|
iso_boot_catalog:
|
||||||
|
|
||||||
|
; Validation entry
|
||||||
|
.validation:
|
||||||
|
db 1 ; Header ID
|
||||||
|
db 0 ; Platform ID (x86)
|
||||||
|
dw 0 ; Reserved
|
||||||
|
times 24 db 0 ; ID string
|
||||||
|
dw 0x55aa ; Checksum
|
||||||
|
dw 0xaa55 ; Key
|
||||||
|
|
||||||
|
; Default entry
|
||||||
|
.default:
|
||||||
|
db 0x88 ; Bootable
|
||||||
|
db 4 ; Hard drive emulation
|
||||||
|
dw 0 ; Load segment (0 is platform default)
|
||||||
|
db 0xEE ; Partition type (0xEE is protective MBR)
|
||||||
|
db 0 ; Unused
|
||||||
|
dw 1 ; Sector count
|
||||||
|
dd 0 ; Start address for virtual disk
|
||||||
|
times 20 db 0 ; Padding
|
||||||
|
|
||||||
|
; EFI section header entry
|
||||||
|
.efi_section_header:
|
||||||
|
db 0x91 ; Final header
|
||||||
|
db 0xEF ; Platform ID (EFI)
|
||||||
|
dw 1 ; Number of section header entries
|
||||||
|
times 28 db 0 ; ID string
|
||||||
|
|
||||||
|
; EFI section entry
|
||||||
|
.efi_section_entry:
|
||||||
|
db 0x88 ; Bootable
|
||||||
|
db 0 ; No emulation
|
||||||
|
dw 0 ; Load segment (0 is platform default)
|
||||||
|
db 0 ; Partition type (not used)
|
||||||
|
db 0 ; Unused
|
||||||
|
dw 512 ; Sector count (1 MiB = 512 CD sectors)
|
||||||
|
dd 512 ; Start address for virtual disk (1 MiB = 512 CD sectors)
|
||||||
|
times 20 db 0 ; Padding
|
||||||
|
|
||||||
|
; Fill until CD sector 0x14
|
||||||
|
times (0x14*2048)-($-$$) db 0
|
||||||
|
|
||||||
|
iso_root_directory:
|
||||||
|
.self:
|
||||||
|
db 0x22 ; Length of entry
|
||||||
|
db 0x00 ; Length of extended attributes
|
||||||
|
db 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 ; Location of extent (0x14)
|
||||||
|
db 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 ; Size of extent
|
||||||
|
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Recording time
|
||||||
|
db 0x02 ; File flags
|
||||||
|
db 0x00 ; Interleaved file unit size
|
||||||
|
db 0x00 ; Interleaved gap size
|
||||||
|
db 0x01, 0x00, 0x00, 0x01 ; Volume sequence number
|
||||||
|
db 0x01 ; Length of file identifier
|
||||||
|
db 0x00 ; File identifier
|
||||||
|
|
||||||
|
.parent:
|
||||||
|
db 0x22 ; Length of entry
|
||||||
|
db 0x00 ; Length of extended attributes
|
||||||
|
db 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 ; Location of extent (0x14)
|
||||||
|
db 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 ; Size of extent
|
||||||
|
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Recording time
|
||||||
|
db 0x02 ; File flags
|
||||||
|
db 0x00 ; Interleaved file unit size
|
||||||
|
db 0x00 ; Interleaved gap size
|
||||||
|
db 0x01, 0x00, 0x00, 0x01 ; Volume sequence number
|
||||||
|
db 0x01 ; Length of file identifier
|
||||||
|
db 0x01 ; File identifier
|
||||||
|
|
||||||
|
.boot_cat:
|
||||||
|
db 0x2C ; Length of entry
|
||||||
|
db 0x00 ; Length of extended attributes
|
||||||
|
db 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13 ; Location of extent (0x13)
|
||||||
|
db 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 ; Size of extent
|
||||||
|
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; Recording time
|
||||||
|
db 0x00 ; File flags
|
||||||
|
db 0x00 ; Interleaved file unit size
|
||||||
|
db 0x00 ; Interleaved gap size
|
||||||
|
db 0x01, 0x00, 0x00, 0x01 ; Volume sequence number
|
||||||
|
db 0x0A ; Length of file identifier
|
||||||
|
db "BOOT.CAT;1",0 ; File identifier
|
||||||
|
|
||||||
|
; Fill until CD sector 0x15
|
||||||
|
times (0x15*2048)-($-$$) db 0
|
|
@ -0,0 +1,56 @@
|
||||||
|
SECTION .text
|
||||||
|
USE32
|
||||||
|
|
||||||
|
long_mode:
|
||||||
|
.func: dq 0
|
||||||
|
.page_table: dd 0
|
||||||
|
|
||||||
|
.entry:
|
||||||
|
; disable interrupts
|
||||||
|
cli
|
||||||
|
|
||||||
|
; disable paging
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, 0x7FFFFFFF
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
; 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 long mode GDT
|
||||||
|
lgdt [gdtr]
|
||||||
|
|
||||||
|
; enable long mode
|
||||||
|
mov ecx, 0xC0000080 ; Read from the EFER MSR.
|
||||||
|
rdmsr
|
||||||
|
or eax, 1 << 11 | 1 << 8 ; Set the Long-Mode-Enable and NXE bit.
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
; set page table
|
||||||
|
mov eax, [.page_table]
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
; enabling paging and protection simultaneously
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 << 31 | 1 << 16 | 1 ;Bit 31: Paging, Bit 16: write protect kernel, Bit 0: Protected Mode
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
; far jump to enable Long Mode and load CS with 64 bit segment
|
||||||
|
jmp gdt.lm64_code:.inner
|
||||||
|
|
||||||
|
USE64
|
||||||
|
|
||||||
|
.inner:
|
||||||
|
; load all the other segments with 64 bit data segments
|
||||||
|
mov rax, gdt.lm64_data
|
||||||
|
mov ds, rax
|
||||||
|
mov es, rax
|
||||||
|
mov fs, rax
|
||||||
|
mov gs, rax
|
||||||
|
mov ss, rax
|
||||||
|
|
||||||
|
; jump to specified function
|
||||||
|
mov rax, [.func]
|
||||||
|
jmp rax
|
|
@ -0,0 +1,67 @@
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
|
||||||
|
; provide function for printing in x86 real mode
|
||||||
|
|
||||||
|
; print a string and a newline
|
||||||
|
; 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
|
||||||
|
; si, ax
|
||||||
|
print:
|
||||||
|
pushf
|
||||||
|
cld
|
||||||
|
.loop:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz .done
|
||||||
|
call print_char
|
||||||
|
jmp .loop
|
||||||
|
.done:
|
||||||
|
popf
|
||||||
|
ret
|
||||||
|
|
||||||
|
; print a character
|
||||||
|
; IN
|
||||||
|
; al: character to print
|
||||||
|
print_char:
|
||||||
|
pusha
|
||||||
|
mov bx, 7
|
||||||
|
mov ah, 0x0e
|
||||||
|
int 0x10
|
||||||
|
popa
|
||||||
|
ret
|
||||||
|
|
||||||
|
; print a number in hex
|
||||||
|
; IN
|
||||||
|
; bx: the number
|
||||||
|
; CLOBBER
|
||||||
|
; al, cx
|
||||||
|
print_hex:
|
||||||
|
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
|
|
@ -0,0 +1,36 @@
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
|
||||||
|
protected_mode:
|
||||||
|
|
||||||
|
.func: dd 0
|
||||||
|
|
||||||
|
.entry:
|
||||||
|
; disable interrupts
|
||||||
|
cli
|
||||||
|
|
||||||
|
; load protected mode GDT
|
||||||
|
lgdt [gdtr]
|
||||||
|
|
||||||
|
; 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.pm32_code:.inner
|
||||||
|
|
||||||
|
USE32
|
||||||
|
|
||||||
|
.inner:
|
||||||
|
; load all the other segments with 32 bit data segments
|
||||||
|
mov eax, gdt.pm32_data
|
||||||
|
mov ds, eax
|
||||||
|
mov es, eax
|
||||||
|
mov fs, eax
|
||||||
|
mov gs, eax
|
||||||
|
mov ss, eax
|
||||||
|
|
||||||
|
; jump to specified function
|
||||||
|
mov eax, [.func]
|
||||||
|
jmp eax
|
|
@ -0,0 +1,222 @@
|
||||||
|
ORG 0x7C00
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
|
||||||
|
stage1: ; 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, stage_msg
|
||||||
|
call print
|
||||||
|
mov al, '1'
|
||||||
|
call print_char
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
; read CHS gemotry
|
||||||
|
; CL (bits 0-5) = maximum sector number
|
||||||
|
; CL (bits 6-7) = high bits of max cylinder number
|
||||||
|
; CH = low bits of maximum cylinder number
|
||||||
|
; DH = maximum head number
|
||||||
|
mov ah, 0x08
|
||||||
|
mov dl, [disk]
|
||||||
|
xor di, di
|
||||||
|
int 0x13
|
||||||
|
jc error ; carry flag set on error
|
||||||
|
mov bl, ch
|
||||||
|
mov bh, cl
|
||||||
|
shr bh, 6
|
||||||
|
mov [chs.c], bx
|
||||||
|
shr dx, 8
|
||||||
|
inc dx ; returns heads - 1
|
||||||
|
mov [chs.h], dx
|
||||||
|
and cl, 0x3f
|
||||||
|
mov [chs.s], cl
|
||||||
|
|
||||||
|
mov eax, (stage2 - stage1) / 512
|
||||||
|
mov bx, stage2
|
||||||
|
mov cx, (stage3.end - stage2) / 512
|
||||||
|
mov dx, 0
|
||||||
|
call load
|
||||||
|
|
||||||
|
mov si, stage_msg
|
||||||
|
call print
|
||||||
|
mov al, '2'
|
||||||
|
call print_char
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
jmp stage2.entry
|
||||||
|
|
||||||
|
; 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 eax, 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
|
||||||
|
|
||||||
|
cmp byte [chs.s], 0
|
||||||
|
jne .chs
|
||||||
|
;INT 0x13 extended read does not work on CDROM!
|
||||||
|
mov dl, [disk]
|
||||||
|
mov si, DAPACK
|
||||||
|
mov ah, 0x42
|
||||||
|
int 0x13
|
||||||
|
jc error ; carry flag set on error
|
||||||
|
ret
|
||||||
|
|
||||||
|
.chs:
|
||||||
|
; calculate CHS
|
||||||
|
xor edx, edx
|
||||||
|
mov eax, [DAPACK.addr]
|
||||||
|
div dword [chs.s] ; divide by sectors
|
||||||
|
mov ecx, edx ; move sector remainder to ecx
|
||||||
|
xor edx, edx
|
||||||
|
div dword [chs.h] ; divide by heads
|
||||||
|
; eax has cylinders, edx has heads, ecx has sectors
|
||||||
|
|
||||||
|
; Sector cannot be greater than 63
|
||||||
|
inc ecx ; Sector is base 1
|
||||||
|
cmp ecx, 63
|
||||||
|
ja error_chs
|
||||||
|
|
||||||
|
; Head cannot be greater than 255
|
||||||
|
cmp edx, 255
|
||||||
|
ja error_chs
|
||||||
|
|
||||||
|
; Cylinder cannot be greater than 1023
|
||||||
|
cmp eax, 1023
|
||||||
|
ja error_chs
|
||||||
|
|
||||||
|
; Move CHS values to parameters
|
||||||
|
mov ch, al
|
||||||
|
shl ah, 6
|
||||||
|
and cl, 0x3f
|
||||||
|
or cl, ah
|
||||||
|
shl dx, 8
|
||||||
|
|
||||||
|
; read from disk using CHS
|
||||||
|
mov al, [DAPACK.count]
|
||||||
|
mov ah, 0x02 ; disk read (CHS)
|
||||||
|
mov bx, [DAPACK.buf]
|
||||||
|
mov dl, [disk]
|
||||||
|
push es ; save ES
|
||||||
|
mov es, [DAPACK.seg]
|
||||||
|
int 0x13
|
||||||
|
pop es ; restore EC
|
||||||
|
jc error ; carry flag set on error
|
||||||
|
ret
|
||||||
|
|
||||||
|
print_dapack:
|
||||||
|
mov bx, [DAPACK.addr + 2]
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov bx, [DAPACK.addr]
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov al, '#'
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
mov bx, [DAPACK.count]
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
mov bx, [DAPACK.seg]
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov al, ':'
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
mov bx, [DAPACK.buf]
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
error_chs:
|
||||||
|
mov ah, 0
|
||||||
|
|
||||||
|
error:
|
||||||
|
call print_line
|
||||||
|
|
||||||
|
mov bh, 0
|
||||||
|
mov bl, ah
|
||||||
|
call print_hex
|
||||||
|
|
||||||
|
mov al, ' '
|
||||||
|
call print_char
|
||||||
|
|
||||||
|
mov si, error_msg
|
||||||
|
call print
|
||||||
|
call print_line
|
||||||
|
.halt:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp .halt
|
||||||
|
|
||||||
|
%include "print.asm"
|
||||||
|
|
||||||
|
stage_msg: db "Stage ",0
|
||||||
|
error_msg: db "ERROR",0
|
||||||
|
|
||||||
|
disk: db 0
|
||||||
|
|
||||||
|
chs:
|
||||||
|
.c: dd 0
|
||||||
|
.h: dd 0
|
||||||
|
.s: dd 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 446-($-$$) db 0
|
||||||
|
partitions: times 4 * 16 db 0
|
||||||
|
db 0x55
|
||||||
|
db 0xaa
|
|
@ -0,0 +1,134 @@
|
||||||
|
SECTION .text
|
||||||
|
USE16
|
||||||
|
|
||||||
|
stage2.entry:
|
||||||
|
; check for required features
|
||||||
|
call cpuid_check
|
||||||
|
|
||||||
|
; enable A20-Line via IO-Port 92, might not work on all motherboards
|
||||||
|
in al, 0x92
|
||||||
|
or al, 2
|
||||||
|
out 0x92, al
|
||||||
|
|
||||||
|
mov dword [protected_mode.func], stage3.entry
|
||||||
|
jmp protected_mode.entry
|
||||||
|
|
||||||
|
%include "cpuid.asm"
|
||||||
|
%include "gdt.asm"
|
||||||
|
%include "long_mode.asm"
|
||||||
|
%include "protected_mode.asm"
|
||||||
|
%include "thunk.asm"
|
||||||
|
|
||||||
|
USE32
|
||||||
|
|
||||||
|
stage3.entry:
|
||||||
|
; stage3 stack at 448 KiB (512KiB minus 64KiB disk buffer)
|
||||||
|
mov esp, 0x70000
|
||||||
|
|
||||||
|
; push arguments
|
||||||
|
mov eax, thunk.int16
|
||||||
|
push eax
|
||||||
|
mov eax, thunk.int15
|
||||||
|
push eax
|
||||||
|
mov eax, thunk.int13
|
||||||
|
push eax
|
||||||
|
mov eax, thunk.int10
|
||||||
|
push eax
|
||||||
|
xor eax, eax
|
||||||
|
mov al, [disk]
|
||||||
|
push eax
|
||||||
|
mov eax, kernel.entry
|
||||||
|
push eax
|
||||||
|
mov eax, [stage3 + 0x18]
|
||||||
|
call eax
|
||||||
|
.halt:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp .halt
|
||||||
|
|
||||||
|
kernel:
|
||||||
|
.stack: dq 0
|
||||||
|
.func: dq 0
|
||||||
|
.args: dq 0
|
||||||
|
|
||||||
|
.entry:
|
||||||
|
; page_table: usize
|
||||||
|
mov eax, [esp + 4]
|
||||||
|
mov [long_mode.page_table], eax
|
||||||
|
|
||||||
|
; stack: u64
|
||||||
|
mov eax, [esp + 8]
|
||||||
|
mov [.stack], eax
|
||||||
|
mov eax, [esp + 12]
|
||||||
|
mov [.stack + 4], eax
|
||||||
|
|
||||||
|
; func: u64
|
||||||
|
mov eax, [esp + 16]
|
||||||
|
mov [.func], eax
|
||||||
|
mov eax, [esp + 20]
|
||||||
|
mov [.func + 4], eax
|
||||||
|
|
||||||
|
; args: *const KernelArgs
|
||||||
|
mov eax, [esp + 24]
|
||||||
|
mov [.args], eax
|
||||||
|
|
||||||
|
; long_mode: usize
|
||||||
|
mov eax, [esp + 28]
|
||||||
|
test eax, eax
|
||||||
|
jz .inner32
|
||||||
|
|
||||||
|
mov eax, .inner64
|
||||||
|
mov [long_mode.func], eax
|
||||||
|
jmp long_mode.entry
|
||||||
|
|
||||||
|
.inner32:
|
||||||
|
; disable paging
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, 0x7FFFFFFF
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
;TODO: PAE (1 << 5)
|
||||||
|
; enable FXSAVE/FXRSTOR, Page Global, and Page Size Extension
|
||||||
|
mov eax, cr4
|
||||||
|
or eax, 1 << 9 | 1 << 7 | 1 << 4
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
; set page table
|
||||||
|
mov eax, [long_mode.page_table]
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
; enabling paging and protection simultaneously
|
||||||
|
mov eax, cr0
|
||||||
|
; Bit 31: Paging, Bit 16: write protect kernel, Bit 0: Protected Mode
|
||||||
|
or eax, 1 << 31 | 1 << 16 | 1
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
; enable FPU
|
||||||
|
;TODO: move to Rust
|
||||||
|
mov eax, cr0
|
||||||
|
and al, 11110011b ; Clear task switched (3) and emulation (2)
|
||||||
|
or al, 00100010b ; Set numeric error (5) monitor co-processor (1)
|
||||||
|
mov cr0, eax
|
||||||
|
fninit
|
||||||
|
|
||||||
|
mov esp, [.stack]
|
||||||
|
mov eax, [.args]
|
||||||
|
push eax
|
||||||
|
mov eax, [.func]
|
||||||
|
call eax
|
||||||
|
.halt32:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp .halt32
|
||||||
|
|
||||||
|
USE64
|
||||||
|
|
||||||
|
.inner64:
|
||||||
|
mov rsp, [.stack]
|
||||||
|
mov rax, [.func]
|
||||||
|
mov rdi, [.args]
|
||||||
|
call rax
|
||||||
|
.halt64:
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
|
jmp .halt64
|
|
@ -0,0 +1,149 @@
|
||||||
|
SECTION .text
|
||||||
|
USE32
|
||||||
|
|
||||||
|
thunk:
|
||||||
|
.int10:
|
||||||
|
mov dword [.func], .int10_real
|
||||||
|
jmp .enter
|
||||||
|
|
||||||
|
.int13:
|
||||||
|
mov dword [.func], .int13_real
|
||||||
|
jmp .enter
|
||||||
|
|
||||||
|
.int15:
|
||||||
|
mov dword [.func], .int15_real
|
||||||
|
jmp .enter
|
||||||
|
|
||||||
|
.int16:
|
||||||
|
mov dword [.func], .int16_real
|
||||||
|
jmp .enter
|
||||||
|
|
||||||
|
.func: dd 0
|
||||||
|
.esp: dd 0
|
||||||
|
.cr0: dd 0
|
||||||
|
|
||||||
|
.enter:
|
||||||
|
; save flags
|
||||||
|
pushfd
|
||||||
|
|
||||||
|
; save registers
|
||||||
|
pushad
|
||||||
|
|
||||||
|
; save esp
|
||||||
|
mov [.esp], esp
|
||||||
|
|
||||||
|
; load gdt
|
||||||
|
lgdt [gdtr]
|
||||||
|
|
||||||
|
; far jump to protected mode 16-bit
|
||||||
|
jmp gdt.pm16_code:.pm16
|
||||||
|
|
||||||
|
.exit:
|
||||||
|
; set segment selectors to 32-bit protected mode
|
||||||
|
mov eax, gdt.pm32_data
|
||||||
|
mov ds, eax
|
||||||
|
mov es, eax
|
||||||
|
mov fs, eax
|
||||||
|
mov gs, eax
|
||||||
|
mov ss, eax
|
||||||
|
|
||||||
|
; restore esp
|
||||||
|
mov esp, [.esp]
|
||||||
|
|
||||||
|
; restore registers
|
||||||
|
popad
|
||||||
|
|
||||||
|
; restore flags
|
||||||
|
popfd
|
||||||
|
|
||||||
|
; return
|
||||||
|
ret
|
||||||
|
|
||||||
|
USE16
|
||||||
|
|
||||||
|
.int10_real:
|
||||||
|
int 0x10
|
||||||
|
ret
|
||||||
|
|
||||||
|
.int13_real:
|
||||||
|
int 0x13
|
||||||
|
ret
|
||||||
|
|
||||||
|
.int15_real:
|
||||||
|
int 0x15
|
||||||
|
ret
|
||||||
|
|
||||||
|
.int16_real:
|
||||||
|
int 0x16
|
||||||
|
ret
|
||||||
|
|
||||||
|
.pm16:
|
||||||
|
; set segment selectors to protected mode 16-bit
|
||||||
|
mov eax, gdt.pm16_data
|
||||||
|
mov ds, eax
|
||||||
|
mov es, eax
|
||||||
|
mov fs, eax
|
||||||
|
mov gs, eax
|
||||||
|
mov ss, eax
|
||||||
|
|
||||||
|
; save cr0
|
||||||
|
mov eax, cr0
|
||||||
|
mov [.cr0], eax
|
||||||
|
|
||||||
|
; disable paging and protected mode
|
||||||
|
and eax, 0x7FFFFFFE
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
; far jump to real mode
|
||||||
|
jmp 0:.real
|
||||||
|
|
||||||
|
.real:
|
||||||
|
; set segment selectors to real mode
|
||||||
|
mov eax, 0
|
||||||
|
mov ds, eax
|
||||||
|
mov es, eax
|
||||||
|
mov fs, eax
|
||||||
|
mov gs, eax
|
||||||
|
mov ss, eax
|
||||||
|
|
||||||
|
; set stack
|
||||||
|
mov esp, 0x7C00 - 64
|
||||||
|
|
||||||
|
; load registers and ES
|
||||||
|
pop es
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
pop ebx
|
||||||
|
pop edx
|
||||||
|
pop ecx
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
; enable interrupts
|
||||||
|
sti
|
||||||
|
|
||||||
|
; call real mode function
|
||||||
|
call [.func]
|
||||||
|
|
||||||
|
; disable interrupts
|
||||||
|
cli
|
||||||
|
|
||||||
|
; save registers and ES
|
||||||
|
push eax
|
||||||
|
push ecx
|
||||||
|
push edx
|
||||||
|
push ebx
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push es
|
||||||
|
|
||||||
|
; load gdt (BIOS sometimes overwrites this)
|
||||||
|
lgdt [gdtr]
|
||||||
|
|
||||||
|
; restore cr0, will enable protected mode
|
||||||
|
mov eax, [.cr0]
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
; far jump to protected mode 32-bit
|
||||||
|
jmp gdt.pm32_code:.exit
|
Loading…
Reference in New Issue