2018-12-20 18:03:39 +01:00
|
|
|
;=----------------------------------------------------------------------------=;
|
|
|
|
; GNU GPL OS/K ;
|
|
|
|
; ;
|
|
|
|
; Authors: spectral` ;
|
|
|
|
; NeoX ;
|
|
|
|
; ;
|
|
|
|
; Desc: Master Boot Record for OS/K ;
|
|
|
|
; (x86_64 architecture only) ;
|
|
|
|
;=----------------------------------------------------------------------------=;
|
|
|
|
|
2018-12-21 14:17:06 +01:00
|
|
|
%define SECOND_STAGE 0x100 ;about to change
|
2018-12-20 18:03:39 +01:00
|
|
|
|
|
|
|
|
2018-12-20 18:19:51 +01:00
|
|
|
[BITS 16] ; real mode
|
|
|
|
[ORG 0x7C00] ; address where the BIOS/UEFI CSM is loading us
|
|
|
|
|
|
|
|
jmp short Start
|
|
|
|
|
|
|
|
;; File Allocation Table Disk Identifiers
|
|
|
|
nop
|
|
|
|
OEM_ID db "GPL OS/K"
|
|
|
|
BytesPerSector dw 0x0200
|
|
|
|
SectorsPerCluster db 0x08
|
|
|
|
ReservedSectors dw 0x0020
|
|
|
|
TotalFATs db 0x02
|
|
|
|
MaxRootEntries dw 0x0000
|
|
|
|
NumberOfSectors dw 0x0000
|
|
|
|
MediaDescriptor db 0xF8
|
|
|
|
SectorsPerFAT dw 0x0000
|
|
|
|
SectorsPerTrack dw 0x003D
|
|
|
|
SectorsPerHead dw 0x0002
|
|
|
|
HiddenSectors dd 0x00000000
|
|
|
|
TotalSectors dd 0x00FE3B1F
|
|
|
|
BigSectorsPerFAT dd 0x00000778
|
|
|
|
Flags dw 0x0000
|
|
|
|
FSVersion dw 0x0000
|
|
|
|
RootDirectoryStart dd 0x00000002
|
|
|
|
FSInfoSector dw 0x0001
|
|
|
|
BackupBootSector dw 0x0006
|
|
|
|
|
|
|
|
TIMES 12 DB 0 ; going to the next offset
|
|
|
|
|
|
|
|
DriveNumber db 0x00
|
|
|
|
ReservedByte db 0x00
|
|
|
|
Signature db 0x29
|
|
|
|
VolumeID dd 0xFFFFFFFF
|
|
|
|
VolumeLabel db "OS/K BDISK "
|
|
|
|
SystemID db "FAT32 "
|
2018-12-20 18:03:39 +01:00
|
|
|
|
|
|
|
Start:
|
2018-12-20 18:19:51 +01:00
|
|
|
;; saving registers for future
|
2018-12-20 18:03:39 +01:00
|
|
|
pushad
|
|
|
|
pushfd
|
|
|
|
pushf
|
2018-12-20 18:19:51 +01:00
|
|
|
|
|
|
|
;; dl contains the boot drive. Saving it.
|
|
|
|
mov [Bootdrv], dl
|
2018-12-20 18:03:39 +01:00
|
|
|
|
|
|
|
;; hello world
|
|
|
|
push si
|
|
|
|
mov si, Starting
|
|
|
|
call PrintB
|
|
|
|
|
2018-12-20 18:19:51 +01:00
|
|
|
;; SWITCHING TO LOADER
|
|
|
|
mov si, Switch
|
2018-12-20 18:03:39 +01:00
|
|
|
call PrintB
|
|
|
|
pop si
|
2018-12-20 18:19:51 +01:00
|
|
|
mov cx, word [SectorsPerCluster] ; size of a cluster in sectors is stored in cx
|
2018-12-20 18:03:39 +01:00
|
|
|
|
2018-12-20 18:19:51 +01:00
|
|
|
; computing location of the begining of the Data area and store in ax
|
|
|
|
mov al, byte [TotalFATs] ; Total number of FATs
|
|
|
|
mul word [BigSectorsPerFAT] ; Number of sectors for a FAT
|
|
|
|
add ax, word [ReservedSectors] ; Find the start of the Data area
|
|
|
|
mov word [Datasector], ax ; Store the begining of the Data area
|
2018-12-20 18:03:39 +01:00
|
|
|
|
2018-12-20 18:19:51 +01:00
|
|
|
; reading 1st data cluster into memory (7C00:0200)
|
|
|
|
mov ax, word [RootDirectoryStart]
|
|
|
|
call ClusterLBA
|
|
|
|
mov bx, 0x0200 ; copy 1st data cluter above bootcode
|
|
|
|
call ReadSectors
|
|
|
|
|
|
|
|
; Point Index register to 1st File Entry
|
|
|
|
mov di, 0x0200 + 0x20
|
|
|
|
;Point to the offset where the file location information contains
|
|
|
|
mov dx, word [di + 0x001A]
|
|
|
|
mov word [Cluster], dx
|
|
|
|
;Set up the segments where the loader needs to be loaded ;)
|
|
|
|
mov ax, 0100h ; set ES:BX = 0100:0000
|
|
|
|
mov es, ax
|
|
|
|
xor bx, bx
|
|
|
|
|
|
|
|
;Read the cluster which contains the loader
|
|
|
|
mov cx, 0x0008
|
|
|
|
mov ax, word [Cluster]
|
|
|
|
call ClusterLBA
|
|
|
|
call ReadSectors
|
|
|
|
|
|
|
|
;Jump to the location where the loader was loded
|
2018-12-20 18:03:39 +01:00
|
|
|
popf
|
|
|
|
popfd
|
|
|
|
popad
|
2018-12-20 18:19:51 +01:00
|
|
|
push word [Bootdrv]
|
|
|
|
call dword SECOND_STAGE:0000
|
|
|
|
|
|
|
|
; Exiting
|
|
|
|
mov ah, 0x00
|
|
|
|
int 0x19 ; warm boot computer
|
|
|
|
|
2018-12-20 18:03:39 +01:00
|
|
|
;;END OF MBR
|
|
|
|
|
|
|
|
;;----------------------------------------------------------------------------;;
|
2018-12-20 18:19:51 +01:00
|
|
|
;; DATA
|
|
|
|
Starting db 0x0A, 0x0D, 0x07, "GNU GPL OS/K", 0x0A, 0x0D, 0x0A, 0x0D, 0
|
|
|
|
Switch db 0x09, " Loading Second Stage", 0
|
|
|
|
AbsoluteSector db 0x00
|
|
|
|
AbsoluteHead db 0x00
|
|
|
|
AbsoluteTrack db 0x00
|
|
|
|
Cluster dw 0x0000
|
|
|
|
Datasector dw 0x0000
|
|
|
|
|
|
|
|
Bootdrv db 0x00
|
|
|
|
|
|
|
|
;; INCLUDES
|
|
|
|
%include "boot/common.inc" ; for PrintB
|
|
|
|
|
|
|
|
;; INTERNAL FUNCTIONS
|
|
|
|
;-------------------------------------------------------------------;
|
|
|
|
; loading second stage loader (loader.s) ;
|
|
|
|
;-------------------------------------------------------------------;
|
|
|
|
ReadSectors:
|
|
|
|
.main:
|
|
|
|
mov di, 0x0005 ; five retries for error
|
|
|
|
.sectorloop:
|
|
|
|
push ax
|
|
|
|
push bx
|
|
|
|
push cx
|
|
|
|
call LbaToChs
|
|
|
|
mov ah, 0x02 ; BIOS read sector
|
|
|
|
mov al, 0x01 ; read one sector
|
|
|
|
mov ch, BYTE [AbsoluteTrack] ; track
|
|
|
|
mov cl, BYTE [AbsoluteSector] ; sector
|
|
|
|
mov dh, BYTE [AbsoluteHead] ; head
|
|
|
|
int 0x13 ; invoke BIOS
|
|
|
|
jnc .success ; test for read error
|
|
|
|
xor ax, ax ; BIOS reset disk
|
|
|
|
int 0x13 ; invoke BIOS
|
|
|
|
dec di ; decrement error counter
|
|
|
|
pop cx
|
|
|
|
pop bx
|
|
|
|
pop ax
|
|
|
|
jnz .sectorloop ; attempt to read again
|
|
|
|
int 0x18
|
|
|
|
.success:
|
|
|
|
pop cx
|
|
|
|
pop bx
|
|
|
|
pop ax
|
|
|
|
add bx, WORD [BytesPerSector] ; queue next buffer
|
|
|
|
inc ax ; queue next sector
|
|
|
|
loop .main ; read next sector
|
|
|
|
ret
|
|
|
|
|
|
|
|
;-------------------------------------------------------------------;
|
|
|
|
; Converts LBA Adresses to CHS ;
|
|
|
|
;-------------------------------------------------------------------;
|
|
|
|
LbaToChs:
|
|
|
|
xor dx, dx ; prepare dx:ax for operation
|
|
|
|
div WORD [SectorsPerTrack] ; calculate
|
|
|
|
inc dl ; adjust for sector 0
|
|
|
|
mov BYTE [AbsoluteSector], dl
|
|
|
|
xor dx, dx ; prepare dx:ax for operation
|
|
|
|
div WORD [SectorsPerHead] ; calculate
|
|
|
|
mov BYTE [AbsoluteHead], dl
|
|
|
|
mov BYTE [AbsoluteTrack], al
|
|
|
|
ret
|
|
|
|
;-------------------------------------------------------------------;
|
|
|
|
; Converts FAT Adresses to LBA ;
|
|
|
|
;-------------------------------------------------------------------;
|
|
|
|
ClusterLBA:
|
|
|
|
sub ax, 0x0002 ; zero base cluster number
|
|
|
|
xor cx, cx
|
|
|
|
mov cl, BYTE [SectorsPerCluster] ; convert byte to word
|
|
|
|
mul cx
|
|
|
|
add ax, WORD [Datasector] ; base data sector
|
|
|
|
ret
|
|
|
|
|
2018-12-20 18:03:39 +01:00
|
|
|
End:
|
2018-12-20 18:19:51 +01:00
|
|
|
times 510-($-$$) db 144 ; NOP until 510
|
|
|
|
dw 0xAA55 ; magic word
|