Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ nasm pure64.asm -o ../bin/pure64.sys -l ../bin/pure64-debug.txt

cd boot

nasm mbr.asm -o ../../bin/mbr.sys
nasm pxestart.asm -o ../../bin/pxestart.sys
nasm multiboot.asm -o ../../bin/multiboot.sys
nasm multiboot2.asm -o ../../bin/multiboot2.sys
nasm uefi.asm -o ../../bin/uefi.sys
nasm bios.asm -o ../../bin/bios.sys -l ../../bin/bios-debug.txt
nasm uefi.asm -o ../../bin/uefi.sys -l ../../bin/uefi-debug.txt

cd ../..
43 changes: 22 additions & 21 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,19 @@ OUTPUT_ARCH("i386:x86-64")

SECTIONS
{
. = 0x100000;
.text : {
*(.text)
}
.data : {
*(.data)
}
.rodata : {
*(.rodata)
}
.bss : {
*(.bss)
}
. = 0x100000;
.text : {
*(.text)
}
.data : {
*(.data)
}
.rodata : {
*(.rodata)
}
.bss : {
*(.bss)
}
}

```
Expand All @@ -108,7 +108,7 @@ extern int main(void);

void _start(void)
{
main();
main();
}
```
This file would **always** have to be linked in front of everything else. For the above example that would mean the linker command above would have to become:
Expand Down Expand Up @@ -231,13 +231,14 @@ MPS INTI flags:
<tr><td>Trigger Mode</td><td>2</td><td>2</td><td>01 Edge-triggered, 11 Level-triggered</td></tr>
</table>

A copy of the E820 System Memory Map is stored at memory address `0x0000000000006000`. Each E820 record is 32 bytes in length and the memory map is terminated by a blank record.
A copy of the UEFI System Memory Map is stored at memory address `0x0000000000006000`. Each UEFI record is 48 bytes in length and the memory map is terminated by a blank record.
<table border="1" cellpadding="2" cellspacing="0">
<tr><th>Variable</th><th>Variable Size</th><th>Description</th></tr>
<tr><td>Starting Address</td><td>64-bit</td><td>The starting address for this record</td></tr>
<tr><td>Length</td><td>64-bit</td><td>The length of memory for this record</td></tr>
<tr><td>Memory Type</td><td>32-bit</td><td>Type 1 is usable memory, Type 2 is not usable</td></tr>
<tr><td>Extended Attributes</td><td>32-bit</td><td>ACPI 3.0 Extended Attributes bitfield</td></tr>
<tr><td>Padding</td><td>64-bit</td><td>Padding for 32-byte alignment</td></tr>
<tr><td>Type</td><td>64-bit</td><td>The type of the memory region</td></tr>
<tr><td>Physical Start</td><td>64-bit</td><td>Physical Address - 4K aligned</td></tr>
<tr><td>Virtual Start</td><td>64-bit</td><td>Virtual Address - 4K aligned</td></tr>
<tr><td>NumberOfPages</td><td>64-bit</td><td>The number of 4K pages in this section</td></tr>
<tr><td>Attribute</td><td>64-bit</td><td>See document linked below</td></tr>
<tr><td>Padding</td><td>64-bit</td><td>Padding</td></tr>
</table>
For more information on the E820 Memory Map: <a href="http://wiki.osdev.org/Detecting_Memory_%28x86%29">OSDev wiki on E820</a>
For more information on the UEFI Memory Map: <a href="https://uefi.org/specs/UEFI/2.9_A/07_Services_Boot_Services.html#efi-boot-services-getmemorymap">UEFI Specs</a>
15 changes: 10 additions & 5 deletions src/boot/pxestart.asm → src/boot/bios-pxe.asm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
; kernel64.sys 16384 bytes (or so)
; =============================================================================

; Set the desired screen resolution values below
Horizontal_Resolution equ 800
Vertical_Resolution equ 600

BITS 16
org 0x7C00
Expand All @@ -31,10 +34,10 @@ start:
mov sp, 0x7C00
sti ; Enable interrupts

mov ah, 0
mov al, 11100011b ; 9600bps, no parity, 1 stop bit, 8 data bits
mov dx, 0 ; Serial port 0
int 0x14 ; Configure serial port
; mov ah, 0
; mov al, 11100011b ; 9600bps, no parity, 1 stop bit, 8 data bits
; mov dx, 0 ; Serial port 0
; int 0x14 ; Configure serial port

; Get the BIOS E820 Memory Map
; use the INT 0x15, eax= 0xE820 BIOS function to get a memory map
Expand Down Expand Up @@ -133,6 +136,8 @@ check_A20:
mov si, msg_OK
call print_string_16

mov bl, 'B' ; 'B' as we booted via BIOS

; 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
Expand Down Expand Up @@ -230,4 +235,4 @@ VBEModeInfoBlock.PhysBasePtr equ VBEModeInfoBlock + 40 ; DD - physical address
VBEModeInfoBlock.Reserved1 equ VBEModeInfoBlock + 44 ; DD - Reserved - always set to 0
VBEModeInfoBlock.Reserved2 equ VBEModeInfoBlock + 48 ; DD - Reserved - always set to 0

; EOF
; EOF
133 changes: 84 additions & 49 deletions src/boot/mbr.asm → src/boot/bios.asm
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,53 @@
; Default location of the second stage boot loader. This loads
; 32 KiB from sector 16 into memory at 0x8000
%define DAP_SECTORS 64
%define DAP_STARTSECTOR 16
%define DAP_STARTSECTOR 262160
%define DAP_ADDRESS 0x8000
%define DAP_SEGMENT 0x0000

; Set the desired screen resolution values below
Horizontal_Resolution equ 800
Vertical_Resolution equ 600

BITS 16
org 0x7C00

entry:
jmp bootcode
nop

; BPB (BIOS Parameter Block)
dq 0 ; OEM identifier
dw 0 ; Bytes per sector
db 0 ; Sectors per cluster
dw 0 ; Reserved sectors
db 0 ; Number of FATs
dw 0 ; Number of root directory entries
dw 0 ; The total sectors in the logical volume
db 0 ; Media descriptor type
dw 0 ; Number of sectors per FAT
dw 0 ; Number of sectors per track
dw 0 ; Number of heads or sides on the storage media
dd 0 ; Number of hidden sectors
dd 0 ; Large sector count

; EBPB (Extended Boot Record)
dd 0 ; Sectors per FAT
dw 0 ; Flags
dw 0 ; FAT version number
dd 0 ; The cluster number of the root directory
dw 0 ; The sector number of the FSInfo structure
dw 0 ; The sector number of the backup boot sector
dq 0 ; Reserved
dd 0 ; Reserved
db 0 ; Drive number
db 0 ; Flags in Windows NT
db 0 ; Signature
dd 0 ; Volume ID 'Serial' number
times 11 db 0 ; Volume label string
dq 0 ; System identifier string. Always "FAT32 "

bootcode:
cli ; Disable interrupts
cld ; Clear direction flag
xor eax, eax
Expand All @@ -33,11 +71,6 @@ entry:

mov [DriveNumber], dl ; BIOS passes drive number in DL

mov ah, 0
mov al, 11100011b ; 9600bps, no parity, 1 stop bit, 8 data bits
mov dx, 0 ; Serial port 0
int 0x14 ; Configure serial port

; 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
Expand Down Expand Up @@ -104,8 +137,8 @@ check_A20:
mov al, 0xDF
out 0x60, al

mov si, msg_Load
call print_string_16
; mov si, msg_Load
; call print_string_16

mov cx, 0x4000 - 1 ; Start looking from here
VBESearch:
Expand All @@ -121,9 +154,9 @@ VBESearch:
jne VBESearch ; Try next mode
cmp byte [VBEModeInfoBlock.BitsPerPixel], 32 ; Desired bit depth
jne VBESearch ; If not equal, try next mode
cmp word [VBEModeInfoBlock.XResolution], 800 ; Desired XRes here
cmp word [VBEModeInfoBlock.XResolution], Horizontal_Resolution ; Desired XRes here
jne VBESearch
cmp word [VBEModeInfoBlock.YResolution], 600 ; Desired YRes here
cmp word [VBEModeInfoBlock.YResolution], Vertical_Resolution ; Desired YRes here
jne VBESearch

or bx, 0x4000 ; Use linear/flat frame buffer model (set bit 14)
Expand All @@ -140,12 +173,15 @@ VBESearch:
jc read_fail

; Verify that the 2nd stage boot loader was read.
mov ax, [0x8006]
cmp ax, 0x3436 ; Match against the Pure64 binary
jne sig_fail
; mov ax, [0x8006]
; cmp ax, 0x3436 ; Match against the Pure64 binary
; jne sig_fail

mov bl, 'B' ; 'B' as we booted via BIOS
; mov [0x5FFF], al ; Store the boot marker

mov si, msg_OK
call print_string_16
; mov si, msg_OK
; call print_string_16

; At this point we are done with real mode and BIOS interrupts. Jump to 32-bit mode.
cli ; No more interrupts
Expand All @@ -156,12 +192,12 @@ VBESearch:
jmp 8:0x8000 ; Jump to 32-bit protected mode

read_fail:
mov si, msg_ReadFail
call print_string_16
jmp halt
; mov si, msg_ReadFail
; call print_string_16
; jmp halt
sig_fail:
mov si, msg_SigFail
call print_string_16
; mov si, msg_SigFail
; call print_string_16
halt:
hlt
jmp halt
Expand All @@ -171,19 +207,19 @@ halt:
;------------------------------------------------------------------------------
; 16-bit function to output a string to the serial port
; IN: SI - Address of start of string
print_string_16: ; Output string in SI to screen
pusha
mov dx, 0 ; Port 0
.repeat:
mov ah, 0x01 ; Serial - Write character to port
lodsb ; Get char from string
cmp al, 0
je .done ; If char is zero, end of string
int 0x14 ; Output the character
jmp short .repeat
.done:
popa
ret
;print_string_16: ; Output string in SI to screen
; pusha
; mov dx, 0 ; Port 0
;.repeat:
; mov ah, 0x01 ; Serial - Write character to port
; lodsb ; Get char from string
; cmp al, 0
; je .done ; If char is zero, end of string
; int 0x14 ; Output the character
; jmp short .repeat
;.done:
; popa
; ret
;------------------------------------------------------------------------------

align 16
Expand All @@ -198,31 +234,30 @@ dw 0xFFFF, 0x0000, 0x9A00, 0x00CF ; 32-bit code descriptor
dw 0xFFFF, 0x0000, 0x9200, 0x00CF ; 32-bit data descriptor
gdt32_end:

msg_Load db 10, "MBR ", 0
msg_OK db "OK", 0
msg_SigFail db "- Bad Sig!", 0
msg_ReadFail db "Failed to read drive!", 0
align 4

times 446-$+$$ db 0
DAP:
db 0x10
db 0x00
dw DAP_SECTORS
dw DAP_ADDRESS
dw DAP_SEGMENT
dq DAP_STARTSECTOR

; 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
;msg_Load db 10, "MBR ", 0
;msg_OK db "OK", 0
;msg_SigFail db "- Bad Sig!", 0
;msg_ReadFail db "Failed to read!", 0

align 4
times 446-$+$$ db 0

DAP:
db 0x10
db 0x00
dw DAP_SECTORS
dw DAP_ADDRESS
dw DAP_SEGMENT
dq DAP_STARTSECTOR
; Partition entries (4x 16-bytes)

times 510-$+$$ db 0

; Boot signature
sign dw 0xAA55

VBEModeInfoBlock: equ 0x5F00
Expand Down
Loading