Commit 7b6d5b4e authored by Ian Seyler's avatar Ian Seyler

Initial commit

parents
*DS_Store
*.sys
; =============================================================================
; Pure64 MBR -- a 64-bit OS/software loader written in Assembly for x86-64 systems
; Copyright (C) 2008-2018 Return Infinity -- see LICENSE.TXT
;
; This Master Boot Record will load Pure64 from a pre-defined location on the
; hard drive without making use of the file system.
;
; In this code we are expecting a BMFS-formatted drive. With BMFS the Pure64
; binary is required to start at sector 16 (8192 bytes from the start). A small
; check is made to make sure Pure64 was loaded by comparing a signiture.
; =============================================================================
; Default location of the second stage boot loader. This loads
; 32 KiB from sector 16 into memory at 0x8000
%define ST2_SECTORS 64
%define ST2_STARTSECTOR 16
%define ST2_ADDRESS 0x8000
%define ST2_SEGMENT 0x0000
; Default location of the third stage boot loader. This loads
; 32 KiB from sector 32 into memory at 0x60000
%define ST3_SECTORS 64
%define ST3_STARTSECTOR 32
%define ST3_ADDRESS 0x0000
%define ST3_SEGMENT 0x6000
USE16
org 0x7C00
entry:
cli ; Disable interrupts
cld ; Clear direction flag
xor eax, eax
mov ss, ax
mov es, ax
mov ds, ax
mov sp, 0x7C00
sti ; Enable interrupts
mov [DriveNumber], dl ; BIOS passes drive number in DL
; Get the BIOS E820 Memory Map
; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
; inputs: es:di -> destination buffer for 24 byte entries
; outputs: bp = entry count, trashes all registers except esi
do_e820:
mov edi, 0x00006000 ; location that memory map will be stored to
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 0x15
jc nomemmap ; carry set on first call means "unsupported function"
mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"
jne nomemmap
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je nomemmap
jmp jmpin
e820lp:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc memmapend ; carry set means "end of list already reached"
mov edx, 0x0534D4150 ; repair potentially trashed register
jmpin:
jcxz skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe notext
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
je skipent
notext:
mov ecx, [es:di + 8] ; get lower dword of memory region length
test ecx, ecx ; is the qword == 0?
jne goodent
mov ecx, [es:di + 12] ; get upper dword of memory region length
jecxz skipent ; if length qword is 0, skip entry
goodent:
inc bp ; got a good entry: ++count, move to next storage spot
add di, 32
skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne e820lp
nomemmap:
; mov byte [cfg_e820], 0 ; No memory map function
memmapend:
xor eax, eax ; Create a blank record for termination (32 bytes)
mov ecx, 8
rep stosd
; Enable the A20 gate
set_A20:
in al, 0x64
test al, 0x02
jnz set_A20
mov al, 0xD1
out 0x64, al
check_A20:
in al, 0x64
test al, 0x02
jnz check_A20
mov al, 0xDF
out 0x60, al
mov si, msg_Load
call print_string_16
mov edi, VBEModeInfoBlock ; VBE data will be stored at this address
mov ax, 0x4F01 ; GET SuperVGA MODE INFORMATION - http://www.ctyme.com/intr/rb-0274.htm
; CX queries the mode, it should be in the form 0x41XX as bit 14 is set for LFB and bit 8 is set for VESA mode
; 0x4112 is 640x480x24bit, 0x4129 should be 32bit
; 0x4115 is 800x600x24bit, 0x412E should be 32bit
; 0x4118 is 1024x768x24bit, 0x4138 should be 32bit
; 0x411B is 1280x1024x24bit, 0x413D should be 32bit
mov cx, 0x4118 ; Put your desired mode here
mov bx, cx ; Mode is saved to BX for the set command later
int 0x10
cmp ax, 0x004F ; Return value in AX should equal 0x004F if command supported and successful
jne halt
cmp byte [VBEModeInfoBlock.BitsPerPixel], 24 ; Make sure this matches the number of bits for the mode!
jne halt ; If set bit mode was unsuccessful then bail out
or bx, 0x4000 ; Use linear/flat frame buffer model (set bit 14)
mov ax, 0x4F02 ; SET SuperVGA VIDEO MODE - http://www.ctyme.com/intr/rb-0275.htm
int 0x10
cmp ax, 0x004F ; Return value in AX should equal 0x004F if supported and successful
jne halt
; Read the 2nd stage boot loader into memory.
mov ah, 0x42 ; Extended Read
mov dl, [DriveNumber] ; http://www.ctyme.com/intr/rb-0708.htm
mov si, ST2_DAP
int 0x13
jc read_fail
; Verify that the 2nd stage boot loader was read.
mov ax, [0x8006]
cmp ax, 0x3436 ; Match against the Pure64 binary
jne magic_fail
; Read the 3rd stage boot loader into memory.
mov ah, 0x42
mov dl, [DriveNumber]
mov si, ST3_DAP
int 0x13
jc read_fail
; At this point we are done with real mode and BIOS interrupts. Jump to 32-bit mode.
cli ; No more interrupts
lgdt [cs:GDTR32] ; Load GDT register
mov eax, cr0
or al, 0x01 ; Set protected mode bit
mov cr0, eax
jmp 8:0x8000 ; Jump to 32-bit protected mode
read_fail:
mov si, msg_ReadFail
call print_string_16
jmp halt
magic_fail:
mov si, msg_MagicFail
call print_string_16
halt:
hlt
jmp halt
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; 16-bit function to print a string to the screen
; IN: SI - Address of start of string
print_string_16: ; Output string in SI to screen
pusha
mov ah, 0x0E ; int 0x10 teletype function
.repeat:
lodsb ; Get char from string
cmp al, 0
je .done ; If char is zero, end of string
int 0x10 ; Otherwise, print it
jmp short .repeat
.done:
popa
ret
;------------------------------------------------------------------------------
align 16
GDTR32: ; Global Descriptors Table Register
dw gdt32_end - gdt32 - 1 ; limit of GDT (size minus one)
dq gdt32 ; linear address of GDT
align 16
gdt32:
dw 0x0000, 0x0000, 0x0000, 0x0000 ; Null desciptor
dw 0xFFFF, 0x0000, 0x9A00, 0x00CF ; 32-bit code descriptor
dw 0xFFFF, 0x0000, 0x9200, 0x00CF ; 32-bit data descriptor
gdt32_end:
msg_Load db "Pure64 MBR v1.0", 0
msg_MagicFail db " - Error!", 0
msg_ReadFail db "Failed to read drive.", 13, 10, 0
times 446-$+$$ db 0
; False partition table entry required by some BIOS vendors.
db 0x80, 0x00, 0x01, 0x00, 0xEB, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
DriveNumber db 0x00
times 476-$+$$ db 0
align 4
ST2_DAP:
db 0x10
db 0x00
dw ST2_SECTORS
dw ST2_ADDRESS
dw ST2_SEGMENT
dq ST2_STARTSECTOR
align 4
ST3_DAP:
db 0x10
db 0x00
dw ST3_SECTORS
dw ST3_ADDRESS
dw ST3_SEGMENT
dq ST3_STARTSECTOR
times 510-$+$$ db 0
sign dw 0xAA55
VBEModeInfoBlock: equ 0x5C00
; VESA
; Mandatory information for all VBE revisions
VBEModeInfoBlock.ModeAttributes equ VBEModeInfoBlock + 0 ; DW - mode attributes
VBEModeInfoBlock.WinAAttributes equ VBEModeInfoBlock + 2 ; DB - window A attributes
VBEModeInfoBlock.WinBAttributes equ VBEModeInfoBlock + 3 ; DB - window B attributes
VBEModeInfoBlock.WinGranularity equ VBEModeInfoBlock + 4 ; DW - window granularity in KB
VBEModeInfoBlock.WinSize equ VBEModeInfoBlock + 6 ; DW - window size in KB
VBEModeInfoBlock.WinASegment equ VBEModeInfoBlock + 8 ; DW - window A start segment
VBEModeInfoBlock.WinBSegment equ VBEModeInfoBlock + 10 ; DW - window B start segment
VBEModeInfoBlock.WinFuncPtr equ VBEModeInfoBlock + 12 ; DD - real mode pointer to window function
VBEModeInfoBlock.BytesPerScanLine equ VBEModeInfoBlock + 16 ; DW - bytes per scan line
; Mandatory information for VBE 1.2 and above
VBEModeInfoBlock.XResolution equ VBEModeInfoBlock + 18 ; DW - horizontal resolution in pixels or characters
VBEModeInfoBlock.YResolution equ VBEModeInfoBlock + 20 ; DW - vertical resolution in pixels or characters
VBEModeInfoBlock.XCharSize equ VBEModeInfoBlock + 22 ; DB - character cell width in pixels
VBEModeInfoBlock.YCharSize equ VBEModeInfoBlock + 23 ; DB - character cell height in pixels
VBEModeInfoBlock.NumberOfPlanes equ VBEModeInfoBlock + 24 ; DB - number of memory planes
VBEModeInfoBlock.BitsPerPixel equ VBEModeInfoBlock + 25 ; DB - bits per pixel
VBEModeInfoBlock.NumberOfBanks equ VBEModeInfoBlock + 26 ; DB - number of banks
VBEModeInfoBlock.MemoryModel equ VBEModeInfoBlock + 27 ; DB - memory model type
VBEModeInfoBlock.BankSize equ VBEModeInfoBlock + 28 ; DB - bank size in KB
VBEModeInfoBlock.NumberOfImagePages equ VBEModeInfoBlock + 29 ; DB - number of image pages
VBEModeInfoBlock.Reserved equ VBEModeInfoBlock + 30 ; DB - reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0)
; Direct Color fields (required for direct/6 and YUV/7 memory models)
VBEModeInfoBlock.RedMaskSize equ VBEModeInfoBlock + 31 ; DB - size of direct color red mask in bits
VBEModeInfoBlock.RedFieldPosition equ VBEModeInfoBlock + 32 ; DB - bit position of lsb of red mask
VBEModeInfoBlock.GreenMaskSize equ VBEModeInfoBlock + 33 ; DB - size of direct color green mask in bits
VBEModeInfoBlock.GreenFieldPosition equ VBEModeInfoBlock + 34 ; DB - bit position of lsb of green mask
VBEModeInfoBlock.BlueMaskSize equ VBEModeInfoBlock + 35 ; DB - size of direct color blue mask in bits
VBEModeInfoBlock.BlueFieldPosition equ VBEModeInfoBlock + 36 ; DB - bit position of lsb of blue mask
VBEModeInfoBlock.RsvdMaskSize equ VBEModeInfoBlock + 37 ; DB - size of direct color reserved mask in bits
VBEModeInfoBlock.RsvdFieldPosition equ VBEModeInfoBlock + 38 ; DB - bit position of lsb of reserved mask
VBEModeInfoBlock.DirectColorModeInfo equ VBEModeInfoBlock + 39 ; DB - direct color mode attributes
; Mandatory information for VBE 2.0 and above
VBEModeInfoBlock.PhysBasePtr equ VBEModeInfoBlock + 40 ; DD - physical address for flat memory frame buffer
VBEModeInfoBlock.Reserved1 equ VBEModeInfoBlock + 44 ; DD - Reserved - always set to 0
VBEModeInfoBlock.Reserved2 equ VBEModeInfoBlock + 48 ; DD - Reserved - always set to 0
; EOF
; =============================================================================
; Pure64 Multiboot -- a 64-bit OS/software loader written in Assembly for x86-64 systems
; Copyright (C) 2008-2017 Return Infinity -- see LICENSE.TXT
;
; http://stackoverflow.com/questions/33488194/creating-a-simple-multiboot-kernel-loaded-with-grub2
; https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format
; =============================================================================
[BITS 32]
[global _start]
[ORG 0x100000] ;If using '-f bin' we need to specify the
;origin point for our code with ORG directive
;multiboot loaders load us at physical
;address 0x100000
FLAG_ALIGN equ 1<<0 ; align loaded modules on page boundaries
FLAG_MEMINFO equ 1<<1 ; provide memory map
FLAG_VIDEO equ 1<<2 ; set video mode
FLAG_AOUT_KLUDGE equ 1<<16
;FLAGS[16] indicates to GRUB we are not
;an ELF executable and the fields
;header address, load address, load end address;
;bss end address and entry address will be available
;in Multiboot header
MAGIC equ 0x1BADB002
;magic number GRUB searches for in the first 8k
;of the kernel file GRUB is told to load
FLAGS equ FLAG_ALIGN | FLAG_MEMINFO | FLAG_VIDEO | FLAG_AOUT_KLUDGE
CHECKSUM equ -(MAGIC + FLAGS)
mode_type equ 0 ; Linear
width equ 1024
height equ 768
depth equ 24
_start: ; We need some code before the multiboot header
xor eax, eax ; Clear eax and ebx in the event
xor ebx, ebx ; we are not loaded by GRUB.
jmp multiboot_entry ; Jump over the multiboot header
align 4 ; Multiboot header must be 32-bit aligned
multiboot_header:
dd MAGIC ; magic
dd FLAGS ; flags
dd CHECKSUM ; checksum
dd multiboot_header ; header address
dd _start ; load address of code entry point
dd 0x00 ; load end address : not necessary
dd 0x00 ; bss end address : not necessary
dd multiboot_entry ; entry address GRUB will start at
dd mode_type
dd width
dd height
dd depth
align 16
multiboot_entry:
push 0
popf
cld ; Clear direction flag
; Copy memory map
mov esi, ebx ; GRUB stores the Multiboot info table at the address in EBX
mov edi, 0x6000 ; We want the memory map stored here
add esi, 44 ; Memory map address at this offset in the Mutliboot table
lodsd ; Grab the memory map size in bytes
mov ecx, eax
lodsd ; Grab the memory map address
mov esi, eax
memmap_entry:
lodsd ; Size of entry
cmp eax, 0
je memmap_end
movsd ; base_addr_low
movsd ; base_addr_high
movsd ; length_low
movsd ; length_high
movsd ; type
xor eax, eax
stosd ; padding
stosd
stosd
jmp memmap_entry
memmap_end:
xor eax, eax
mov ecx, 8
rep stosd
; Copy loader and kernel to expected location
mov esi, multiboot_end
mov edi, 0x00008000
mov ecx, 8192 ; Copy 32K
rep movsd ; Copy loader to expected address
cli
jmp 0x00008000
times 512-$+$$ db 0 ; Padding
multiboot_end:
; =============================================================================
; EOF
; =============================================================================
; Pure64 Multiboot 2 -- a 64-bit OS/software loader written in Assembly for x86-64 systems
; Copyright (C) 2008-2017 Return Infinity -- see LICENSE.TXT
;
; http://nongnu.askapache.com/grub/phcoder/multiboot.pdf
; =============================================================================
[BITS 32]
[global _start]
[ORG 0x100000] ;If using '-f bin' we need to specify the
;origin point for our code with ORG directive
;multiboot loaders load us at physical
;address 0x100000
MAGIC equ 0xE85250D6
ARCHITECHTURE equ 0
HEADER_LENGTH equ multiboot_header_end - multiboot_header_start
CHECKSUM equ 0x100000000 - (MAGIC + ARCHITECHTURE + HEADER_LENGTH)
_start: ; We need some code before the multiboot header
xor eax, eax ; Clear eax and ebx in the event
xor ebx, ebx ; we are not loaded by GRUB.
jmp multiboot_entry ; Jump over the multiboot header
align 8 ; Multiboot 2 header must be 64-bit aligned
multiboot_header_start:
dd MAGIC
dd ARCHITECHTURE
dd HEADER_LENGTH
dd CHECKSUM
entry_address_tag_start:
dw 3
dw 0
dd entry_address_tag_end - entry_address_tag_start
dq multiboot_entry
entry_address_tag_end:
framebuffer_tag_start:
dw 5
dw 0
dd framebuffer_tag_end - framebuffer_tag_start
dd 800
dd 600
dd 32
framebuffer_tag_end:
dw 0 ; End type
dw 0
dd 8
multiboot_header_end:
multiboot_entry:
cmp eax, 0x36D76289 ; Magic value
jne error
error:
jmp $
; =============================================================================
; Pure64 PXE Start -- a 64-bit OS/software loader written in Assembly for x86-64 systems
; Copyright (C) 2008-2018 Return Infinity -- see LICENSE.TXT
;
; This is a stub file for loading Pure64 and a kernel/software package via PXE.
;
; Windows - copy /b pxestart.bin + pure64.sys + kernel64.sys pxeboot.bin
; Unix - cat pxestart.bin pure64.sys kernel64.sys > pxeboot.bin
;
; Max size of the resulting pxeboot.bin is 33792 bytes. 1K for the PXE loader
; stub and up to 32KiB for the code/data. PXE loads the file to address
; 0x00007C00 (Just like a boot sector).
;
; File Sizes
; pxestart.bin 1024 bytes
; pure64.sys 4096 bytes
; kernel64.sys 16384 bytes (or so)
; =============================================================================
USE16
org 0x7C00
start:
cli ; Disable interrupts
cld ; Clear direction flag
xor eax, eax
mov ss, ax
mov es, ax
mov ds, ax
mov sp, 0x7C00
sti ; Enable interrupts
; Get the BIOS E820 Memory Map
; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
; inputs: es:di -> destination buffer for 24 byte entries
; outputs: bp = entry count, trashes all registers except esi
do_e820:
mov edi, 0x00006000 ; location that memory map will be stored to
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx, 0x0534D4150 ; Place "SMAP" into edx
mov eax, 0xe820
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes
int 0x15
jc nomemmap ; carry set on first call means "unsupported function"
mov edx, 0x0534D4150 ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"
jne nomemmap
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je nomemmap
jmp jmpin
e820lp:
mov eax, 0xe820 ; eax, ecx get trashed on every int 0x15 call
mov [es:di + 20], dword 1 ; force a valid ACPI 3.X entry
mov ecx, 24 ; ask for 24 bytes again
int 0x15
jc memmapend ; carry set means "end of list already reached"
mov edx, 0x0534D4150 ; repair potentially trashed register
jmpin:
jcxz skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe notext
test byte [es:di + 20], 1 ; if so: is the "ignore this data" bit clear?
je skipent
notext:
mov ecx, [es:di + 8] ; get lower dword of memory region length
test ecx, ecx ; is the qword == 0?
jne goodent
mov ecx, [es:di + 12] ; get upper dword of memory region length
jecxz skipent ; if length qword is 0, skip entry
goodent:
inc bp ; got a good entry: ++count, move to next storage spot
add di, 32
skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne e820lp
nomemmap:
; mov byte [cfg_e820], 0 ; No memory map function
memmapend:
xor eax, eax ; Create a blank record for termination (32 bytes)
mov ecx, 8
rep stosd
; Enable the A20 gate
set_A20:
in al, 0x64
test al, 0x02
jnz set_A20
mov al, 0xD1
out 0x64, al
check_A20:
in al, 0x64
test al, 0x02
jnz check_A20
mov al, 0xDF
out 0x60, al
mov si, msg_Load ; Print message
call print_string_16
mov edi, VBEModeInfoBlock ; VBE data will be stored at this address
mov ax, 0x4F01 ; GET SuperVGA MODE INFORMATION - http://www.ctyme.com/intr/rb-0274.htm
; CX queries the mode, it should be in the form 0x41XX as bit 14 is set for LFB and bit 8 is set for VESA mode
; 0x4112 is 640x480x24bit, 0x4129 should be 32bit
; 0x4115 is 800x600x24bit, 0x412E should be 32bit
; 0x4118 is 1024x768x24bit, 0x4138 should be 32bit
; 0x411B is 1280x1024x24bit, 0x413D should be 32bit
mov cx, 0x4118 ; Put your desired mode here
mov bx, cx ; Mode is saved to BX for the set command later
int 0x10
cmp ax, 0x004F ; Return value in AX should equal 0x004F if command supported and successful
jne halt
cmp byte [VBEModeInfoBlock.BitsPerPixel], 24 ; Make sure this matches the number of bits for the mode!
jne halt ; If set bit mode was unsuccessful then bail out
or bx, 0x4000 ; Use linear/flat frame buffer model (set bit 14)
mov ax, 0x4F02 ; SET SuperVGA VIDEO MODE - http://www.ctyme.com/intr/rb-0275.htm
int 0x10
cmp ax, 0x004F ; Return value in AX should equal 0x004F if supported and successful
jne halt
mov ax, [0x8006]
cmp ax, 0x3436 ; Match against the Pure64 binary
jne magic_fail
; At this point we are done with real mode and BIOS interrupts. Jump to 32-bit mode.
cli ; No more interrupts
lgdt [cs:GDTR32] ; Load GDT register
mov eax, cr0
or al, 0x01 ; Set protected mode bit
mov cr0, eax
jmp 8:0x8000 ; Jump to 32-bit protected mode
magic_fail:
mov si, msg_MagicFail
call print_string_16
halt:
hlt
jmp halt
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; 16-bit Function to print a string to the screen
; input: SI - Address of start of string
print_string_16: ; Output string in SI to screen
pusha
mov ah, 0x0E ; int 0x10 teletype function
.repeat:
lodsb ; Get char from string
test al, al
jz .done ; If char is zero, end of string
int 0x10 ; Otherwise, print it
jmp short .repeat
.done:
popa
ret
;------------------------------------------------------------------------------
align 16
GDTR32: ; Global Descriptors Table Register
dw gdt32_end - gdt32 - 1 ; limit of GDT (size minus one)
dq gdt32 ; linear address of GDT
align 16
gdt32:
dw 0x0000, 0x0000, 0x0000, 0x0000 ; Null desciptor
dw 0xFFFF, 0x0000, 0x9A00, 0x00CF ; 32-bit code descriptor
dw 0xFFFF, 0x0000, 0x9200, 0x00CF ; 32-bit data descriptor
gdt32_end:
msg_Load db "Pure64 PXE v1.0", 0
msg_MagicFail db " - Error!", 0
times 510-$+$$ db 0 ; Pad out for a normal boot sector
sign dw 0xAA55 ; BIOS boot sector signature
times 1024-$+$$ db 0 ; Padding so that Pure64 will be aligned at 0x8000
VBEModeInfoBlock: equ 0x5C00
; VESA
; Mandatory information for all VBE revisions
VBEModeInfoBlock.ModeAttributes equ VBEModeInfoBlock + 0 ; DW - mode attributes
VBEModeInfoBlock.WinAAttributes equ VBEModeInfoBlock + 2 ; DB - window A attributes
VBEModeInfoBlock.WinBAttributes equ VBEModeInfoBlock + 3 ; DB - window B attributes
VBEModeInfoBlock.WinGranularity equ VBEModeInfoBlock + 4 ; DW - window granularity in KB
VBEModeInfoBlock.WinSize equ VBEModeInfoBlock + 6 ; DW - window size in KB
VBEModeInfoBlock.WinASegment equ VBEModeInfoBlock + 8 ; DW - window A start segment
VBEModeInfoBlock.WinBSegment equ VBEModeInfoBlock + 10 ; DW - window B start segment
VBEModeInfoBlock.WinFuncPtr equ VBEModeInfoBlock + 12 ; DD - real mode pointer to window function
VBEModeInfoBlock.BytesPerScanLine equ VBEModeInfoBlock + 16 ; DW - bytes per scan line
; Mandatory information for VBE 1.2 and above
VBEModeInfoBlock.XResolution equ VBEModeInfoBlock + 18 ; DW - horizontal resolution in pixels or characters
VBEModeInfoBlock.YResolution equ VBEModeInfoBlock + 20 ; DW - vertical resolution in pixels or characters
VBEModeInfoBlock.XCharSize equ VBEModeInfoBlock + 22 ; DB - character cell width in pixels
VBEModeInfoBlock.YCharSize equ VBEModeInfoBlock + 23 ; DB - character cell height in pixels
VBEModeInfoBlock.NumberOfPlanes equ VBEModeInfoBlock + 24 ; DB - number of memory planes
VBEModeInfoBlock.BitsPerPixel equ VBEModeInfoBlock + 25 ; DB - bits per pixel
VBEModeInfoBlock.NumberOfBanks equ VBEModeInfoBlock + 26 ; DB - number of banks
VBEModeInfoBlock.MemoryModel equ VBEModeInfoBlock + 27 ; DB - memory model type
VBEModeInfoBlock.BankSize equ VBEModeInfoBlock + 28 ; DB - bank size in KB
VBEModeInfoBlock.NumberOfImagePages equ VBEModeInfoBlock + 29 ; DB - number of image pages
VBEModeInfoBlock.Reserved equ VBEModeInfoBlock + 30 ; DB - reserved (0x00 for VBE 1.0-2.0, 0x01 for VBE 3.0)
; Direct Color fields (required for direct/6 and YUV/7 memory models)
VBEModeInfoBlock.RedMaskSize equ VBEModeInfoBlock + 31 ; DB - size of direct color red mask in bits
VBEModeInfoBlock.RedFieldPosition equ VBEModeInfoBlock + 32 ; DB - bit position of lsb of red mask
VBEModeInfoBlock.GreenMaskSize equ VBEModeInfoBlock + 33 ; DB - size of direct color green mask in bits
VBEModeInfoBlock.GreenFieldPosition equ VBEModeInfoBlock + 34 ; DB - bit position of lsb of green mask
VBEModeInfoBlock.BlueMaskSize equ VBEModeInfoBlock + 35 ; DB - size of direct color blue mask in bits
VBEModeInfoBlock.BlueFieldPosition equ VBEModeInfoBlock + 36 ; DB - bit position of lsb of blue mask
VBEModeInfoBlock.RsvdMaskSize equ VBEModeInfoBlock + 37 ; DB - size of direct color reserved mask in bits
VBEModeInfoBlock.RsvdFieldPosition equ VBEModeInfoBlock + 38 ; DB - bit position of lsb of reserved mask
VBEModeInfoBlock.DirectColorModeInfo equ VBEModeInfoBlock + 39 ; DB - direct color mode attributes
; Mandatory information for VBE 2.0 and above
VBEModeInfoBlock.PhysBasePtr equ VBEModeInfoBlock + 40 ; DD - physical address for flat memory frame buffer
VBEModeInfoBlock.Reserved1 equ VBEModeInfoBlock + 44 ; DD - Reserved - always set to 0
VBEModeInfoBlock.Reserved2 equ VBEModeInfoBlock + 48 ; DD - Reserved - always set to 0
; EOF
#!/bin/bash
nasm pure64.asm -o pure64.sys
cd bootsectors
nasm mbr.asm -o ../mbr.sys
nasm pxestart.asm -o ../pxestart.sys
nasm multiboot.asm -o ../multiboot.sys
nasm multiboot2.asm -o ../multiboot2.sys
cd ..
#!/bin/sh
rm -f *.sys
; =============================================================================
; Pure64 -- a 64-bit OS/software loader written in Assembly for x86-64 systems
; Copyright (C) 2008-2017 Return Infinity -- see LICENSE.TXT
;
; INIT ACPI
; =============================================================================
init_acpi:
mov rsi, 0x00000000000E0000 ; Start looking for the Root System Description Pointer Structure
mov rbx, 'RSD PTR ' ; This in the Signature for the ACPI Structure Table (0x2052545020445352)
searchingforACPI:
lodsq ; Load a quad word from RSI and store in RAX, then increment RSI by 8
cmp rax, rbx
je foundACPI
cmp rsi, 0x00000000000FFFFF ; Keep looking until we get here
jge noACPI ; ACPI tables couldn't be found, Fail.
jmp searchingforACPI
foundACPI: ; Found a Pointer Structure, verify the checksum
push rsi
xor ebx, ebx
mov ecx, 20 ; As per the spec only the first 20 bytes matter
sub rsi, 8 ; Bytes 0 thru 19 must sum to zero
nextchecksum:
lodsb ; Get a byte
add bl, al ; Add it to the running total
sub cl, 1
cmp cl, 0
jne nextchecksum
pop rsi
cmp bl, 0
jne searchingforACPI ; Checksum didn't check out? Then keep looking.
lodsb ; Checksum
lodsd ; OEMID (First 4 bytes)
lodsw ; OEMID (Last 2 bytes)
lodsb ; Grab the Revision value (0 is v1.0, 1 is v2.0, 2 is v3.0, etc)
cmp al, 0
je foundACPIv1 ; If AL is 0 then the system is using ACPI v1.0
jmp foundACPIv2 ; Otherwise it is v2.0 or higher
foundACPIv1:
xor eax, eax
lodsd ; Grab the 32 bit physical address of the RSDT (Offset 16).
mov rsi, rax ; RSI now points to the RSDT
lodsd ; Grab the Signiture
cmp eax, 'RSDT' ; Make sure the signiture is valid
jne novalidacpi ; Not the same? Bail out
sub rsi, 4
mov [os_ACPITableAddress], rsi ; Save the RSDT Table Address
add rsi, 4
xor eax, eax