It is to be a 64 bit only operating system, so I thought I should employ the biggest form of partitions i.e. the GPT
Also, I will be using my own 64Bit File System for maximum HDD space usage.
I plan for my MBR to boot from GPT partitions first and if none exist fall back to the MBR partitions, this way I can maximise my usage whilst
maintaining compatibility.
I was going to attempt to boot using EFI, however I could not get a cross compiler with the correct output formats or the code to use different outputs.
Also, to get this to work I need a CRC32 function, but I have no idea how to do this in real mode assembly...
So here is what I have, obviously I have yet to add the actual GPT entries, but I have the MBR Partition table and the GPT header.
Code: Select all
; This is the Meganet OS-4 MBR
; It uses bot the MBR and the GPT, giving preference to
; entries in th GPT.
struc GPTHeader
Signature resq 1 ; Should be "EFI PART"
Revision resw 1 ; in format 00 00 MA MI (MA = Major, MI = Minor) so 00 00 01 00 is 1.0
Headersize resw 1 ; The size of this structure (Usually 5C 00 00 00) 92 Bytes
HeaderCRC resw 1 ; CRC32 of the header
MBZ resw 1 ; Should be zero
CurrentLBA resq 1 ; Location of this header (1)
BackupLBA resq 1 ; The location of the backup copy of this header LBA-1
PartsFirstLBA resq 1 ; The first usable LBA for partitions
PartsLastLBA resq 1 ; The last usable LBA for partitions
DiskGUID resb 16 ; The disk GUID
Partitions resq 1 ; Should be 2
PartCount resw 1 ; The number of partiotn entries
PartEntSize resw 1 ; The size (In Bytes) or a partiotn entry
PartCRC resw 1 ; The CRC32 of the partiotn entry array
endstruc
struc GPTEntry
PartitionTypeGUID resb 16 ; The GUID representing the partition type
PartitionGUID resb 16 ; The partitions unique GUID
FirstLBA resq 1 ; The partition starting LBA (little-endian)
LastLBA resq 1 ; The partitions last LBA (Inclusive, usually odd
Flags resq 1 ; The partitions Attribute Flags
PartitionName resb 72 ; The name of the partition (36 UTF-16LE code units)
endstruc
struc MBRPartitionEntry
BootFlag resb 1 ; 0x80 = Active 0x00 = Non-Active
BeginHead resb 1 ; Starting Sector CHS Head
BeginSector resb 1 ; Starting Sector CHS Head
BeginCyl resb 1 ; Starting Sector CHS Head
SystemID resb 1 ; The SystemID A.K.A. Partition Type
EndHead resb 1 ; End Sector CHS Head
EndSector resb 1 ; End Sector CHS Head
EndCyl resb 1 ; End Sector CHS Head
RelSectorLow resw 1 ;
RelSectorHigh resw 1
NumSectorsLow resw 1
NumSectorsHigh resw 1
endstruc
[SECTION .text]
[BITS 16]
[ORG 0x0600]
; Disable interrupts
cli
; Initialise the segment registers
xor ax,ax
mov ds,ax
mov es,ax
; Initialise the stack
mov ss, ax
mov sp, 0x7C00
; enable interrupts
sti
mov si, _relocating_msg
call print_string_16
; Copy the MBR to 0x0600
cld
mov si, sp
mov di, 0x0600
mov cx, 512/2
repne movsw
jmp 0x0000:next
next:
; Save the Drive Number passed by the BIOS in DL
mov [BiosDriveNumber], DL
mov si, _done_msg
call print_string_16
; This is where we continue
; after being moved from 0x7C00 to 0x0600
; Check if drive supports LBA
mov ah,0x41
mov bx,0x55AA
mov dl,[BiosDriveNumber]
int 0x13
cmp bx,0xAA55
jne _no_gpt
;Read LBA1 (GPT Header) to 0x8000
push ds
.reset:
mov ax, 0
mov dl, [BiosDriveNumber]
int 0x13
jc .reset
pop ds
mov ah, 0x42
mov dl, [BiosDriveNumber]
lea si, [lbaadr]
int 0x13
cmp ah, 0x00
jne _no_gpt
mov si, _reading_gpt_msg
call print_string_16
; Check the GPT Signature
;db 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54
cmp dword [0x8000], 0x20494645
jne _no_gpt
cmp dword [0x8004], 0x54524150
jne _no_gpt
; Jump to _gpt_ok if the signature check was ok
je _gpt_ok
; We are here if the above signature check failed
_no_gpt:
mov si, _fail_msg
call print_string_16
jmp _mbr_fallback
; Protect from running through into data
jmp $ ; this is temporary
; We reach this point if the GPT signature check was ok
_gpt_ok:
; ####TEMP####
mov si, _GPT_sig_ok
call print_string_16
; ####TEMP####
jmp $
; We reach this point if we need to use legacy MBR
_mbr_fallback:
mov si, _reading_MBR_msg
call print_string_16
; check if first partition is active
mov ax, 1
cmp byte [0x7BBE], 0x80
je _found_mbr_active_part
inc ax
cmp byte [0x7BCF], 0x80
je _found_mbr_active_part
inc ax
cmp byte [0x7BDF], 0x80
je _found_mbr_active_part
inc ax
cmp byte [0x7BEF], 0x80
je _found_mbr_active_part
; At this point both GPT and MBR boot have failed
mov si, _fail_msg
call print_string_16
jmp $
; We reach this point if we have found an active MBR partition to boot from
_found_mbr_active_part:
; ####TEMP####
mov si, _MBR_part_act
call print_string_16
; ####TEMP####
jmp $
lbaadr:
db 0x10 ; packet size (16 bytes)
db 0x00 ; reserved, must be 0
db 0x20 ; number of sectors to transfer
db 0x00 ; reserved, must be 0
dw 0x0000 ; Buffer's segment
dw 0x0800 ; Buffer's offset
dq 0x0000000000000001 ; 64-bit starting sector number
; 16-bit Function to print a sting 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
cmp al, 0
je .done ; If char is zero, end of string
int 0x10 ; Otherwise, print it
jmp short .repeat
.done:
popa
ret
; Data area
BiosDriveNumber db 0
SectorBufferOffset dw 0x8000
TempCheck dw 0
SecondaryGPTHeader dq 0
; Permanent strings
_relocating_msg db 'Relocating MBR... ', 0
_reading_gpt_msg db 'Reading GPT... ', 0
_reading_MBR_msg db 'Reading MBR... ', 0
_fail_msg db 'FAILED!', 13, 10, 0
_done_msg db 'DONE.', 13, 10, 0
; Temporary string
_GPT_sig_ok db 'GPT SIG OK ', 0
_MBR_part_act db 'MBR PART ACTIVE FOUND ', 0
; Pad this stub MBR (With NOP's)
times 446-$+$$ db 0x90
; Space for the MBR Partition Table
PartitionTable:
db 0x80, '###############################################################'
;PartitionTable resb 4 * MBRPartitionEntry_size
; MBR's boot sig
sign dw 0xAA55
; Hardcoded GPT signature
db 0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54