Adding FAT in the mbr, moving test and 'work' in the loader

This commit is contained in:
Adrien Bourmault 2018-12-20 18:19:51 +01:00
parent 7841d71656
commit e1302cdbac
12 changed files with 230 additions and 903 deletions

View File

View File

@ -1,25 +0,0 @@
;=----------------------------------------------------------------------------=;
; GNU GPL OS/K ;
; ;
; Authors: spectral` ;
; NeoX ;
; ;
; Desc: Functions for the OS/K loaders ;
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
;-------------------------------------------------------------------;
; Prints the (null-terminated) string at address @es:@si ;
;-------------------------------------------------------------------;
PrintB:
pushad ; saving context
.pLoop:
lodsb ; loads the character at @es:@si in @al
cmp al,0
je .pEnd ; while @al, i.e. while we're not hitting '\0'
mov ah, 0x0E
int 0x10 ; print character @al in color @bl (BIOS interrupt)
jmp .pLoop
.pEnd:
popad ; restores context
ret

View File

@ -1,83 +0,0 @@
;=----------------------------------------------------------------------------=;
; GNU GPL OS/K ;
; ;
; Authors: spectral` ;
; NeoX ;
; ;
; Desc: Functions for the OS/K kernel loader ;
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
;-------------------------------------------------------------------;
; Setting the pages for long model ;
;-------------------------------------------------------------------;
[BITS 16]
PagingSetting:
;clear tables
mov edi, 0x1000
mov cr3, edi
xor eax, eax
mov ecx, 4096
rep stosd
mov edi, cr3
;set up new tables
mov DWORD [edi], 0x2003
add edi, 0x1000
mov DWORD [edi], 0x3003
add edi, 0x1000
mov DWORD [edi], 0x4003
add edi, 0x1000
mov ebx, 0x00000003
mov ecx, 512
.setEntry:
mov DWORD [edi], ebx
add ebx, 0x1000
add edi, 8
loop .setEntry
;enable PAE bit in CR4
mov eax, cr4
or eax, 1<<5
mov cr4, eax
;switch from REAL MODE
;set long mode bit
mov ecx, 0xc0000080
rdmsr
or eax, 1<<8
wrmsr
;enable paging
mov eax, cr0
or eax, 1<<31
mov cr0, eax
ret

View File

@ -10,8 +10,7 @@
[ORG 0x1000]
pop ax
mov [Bootdrv], ax
pop word [Bootdrv]
jmp main
;; DATA
@ -126,9 +125,67 @@ get_dimensions:
pop ebx
pop eax
ret
;-----------------------------------------------------------------------;
; Checks if the CPU is compatible with 64-bits operating systems ;
; If the 21th bit of the eax register is set, then CPUID is supported ;
; We then test CPUID's result to see if long mode is supported ;
;-----------------------------------------------------------------------;
Is64bits:
pushfd ; recovering the flags in eax
pop eax
mov ecx, eax
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, ecx
shr eax, 21
and eax, 1 ; magical spell of murta
push ecx
popfd
test eax, eax
jz .NonCompat ; if (CPUID non supporté) goto NonCompat
mov eax, 0x80000000
cpuid
cmp eax, 0x80000001
jb .NonCompat ; if (eax <= 0x80000001) goto NonCompat
mov eax, 0x80000001
cpuid
test edx, 1 << 29
jz .NonCompat ; if (edx != 1 << 29) goto NonCompat
ret ; back to mbr.s
.NonCompat:
stc
ret
;; INCLUDES
%include "boot/common.inc" ; for PrintB
main:
;; DISABLING CURSOR BLINKING AND GETTING INFOS
;; compatibility check
mov si, Init
call PrintB
pop si
call Is64bits
jc ErrorNo64
push si
mov si, Pass
call PrintB
;; enabling A20
mov si, EnA20
call PrintB
pop si
in al, 0x92
or al, 2
out 0x92, al
push si
mov si, Pass
call PrintB
;; DISABLING CURSOR BLINKING AND GETTING INFOS
call get_dimensions
call disable_cursor
@ -263,6 +320,10 @@ write:
;; DATA
txt db 0x09, " Switching to Long Mode... OK", 0x0A, 0x0D, 0
Init db 0x09, " Checking CPUID", 0
EnA20 db 0x09, " Enabling A20 line", 0
NoLongMode db 0x0A, 0x0D, "ERROR: Your computer is not designed for x64 OS", 0
Pass db " OK", 0x0A, 0x0D, 0
NextTRAM dq 0x0B8AA0 ; Last position of cursor
VIDEO_MODE64 dq 0
VGA_HEIGHT64 dq 0
@ -298,6 +359,15 @@ main64:
;call KERNEL
jmp $
[BITS 16]
ErrorNo64:
mov si, NoLongMode
call PrintB
Die:
cli
hlt ; die nooooow
retf
times 1024-($-$$) db 144
KERNEL:

View File

@ -1,372 +0,0 @@
;=----------------------------------------------------------------------------=;
; GNU GPL OS/K ;
; ;
; Authors: spectral` ;
; NeoX ;
; ;
; Desc: Kernel (second stage) Loader for OS/K ;
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
[ORG 0x1000]
pop word [Bootdrv]
jmp main
;; DATA
%define TRAM 0x0B8000 ; [T]ext[RAM]
%define VRAM 0x0A0000 ; [V]ideo[RAM]
Bootdrv db 0x00
VGA_HEIGHT dq 0
VIDEO_MODE dw 0
;; GDT WITH DOC
GDT64:
NULL_SELECTOR: ;; null selector within 64 bits
dw GDT_LENGTH ; limit of GDT
dw GDT64 ; linear address of GDT
dd 0x0
CODE_SELECTOR: ;; 32-bit code selector (ring 0)
dw 0x0FFFF ; Segment Limit 15:00
db 0x0, 0x0, 0x0 ; Base Address 23:00
db 10011010b ; |7|6|5|4|3|2|1|0|
; | | | | | | | `----- 1 when segment used.
; | | | | | | `------ 1 when writable.
; | | | | | `------- 1 if "conformant". Don't know what is it... spectral ? xD
; | | | | `-------- 1 always
; | | | `--------- 1 for segment descriptor, 0 for system descriptor
; | | `---------- DPL !!! 0 for ring 0
; | `----------- DPL (2/2)
; `------------ 1 if in physical memory, 0 if page fault
db 11001111b ; |7|6|5|4|3|2|1|0|
; | | | | | | | `----- Limit 16
; | | | | | | `------ Limit 17
; | | | | | `------- Limit 18
; | | | | `-------- Limit 19
; | | | `--------- available for use
; | | `---------- 0 always
; | `----------- size of data. 1 for 32bits
; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko)
db 0x0 ; Base Address 31:24
DATA_SELECTOR: ;; flat data selector (ring 0)
dw 0x0FFFF ; Segment Limit 15:00
db 0x0, 0x0, 0x0 ; Base Address 23:00
db 10010010b ; |7|6|5|4|3|2|1|0|
; | | | | | | | `----- 1 when segment used.
; | | | | | | `------ 1 when writable.
; | | | | | `------- expansion direction. 1 for a LIFO
; | | | | `-------- 1 always
; | | | `--------- 1 for segment descriptor, 0 for system descriptor
; | | `---------- DPL !!! 0 for ring 0
; | `----------- DPL (2/2)
; `------------ 1 if in physical memory, 0 if page fault
db 10001111b ; |7|6|5|4|3|2|1|0|
; | | | | | | | `----- Limit 16
; | | | | | | `------ Limit 17
; | | | | | `------- Limit 18
; | | | | `-------- Limit 19
; | | | `--------- available for use
; | | `---------- 0 always
; | `----------- size of data. 1 for 32bits
; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko)
db 0x0 ; Base Address 31:24
LONG_SELECTOR: ;; 64-bit code selector (ring 0)
dw 0x0FFFF ; Segment Limit 15:00
db 0x0, 0x0, 0x0 ; Base Address 23:00
db 10011010b ; |7|6|5|4|3|2|1|0|
; | | | | | | | `----- 1 when segment used.
; | | | | | | `------ 1 when writable.
; | | | | | `------- 1 if "conformant". Don't know what is it... spectral ? xD
; | | | | `-------- 1 always
; | | | `--------- 1 for segment descriptor, 0 for system descriptor
; | | `---------- DPL !!! 0 for ring 0
; | `----------- DPL (2/2)
; `------------ 1 if in physical memory, 0 if page fault
db 10101111b ; |7|6|5|4|3|2|1|0|
; | | | | | | | `----- Limit 16
; | | | | | | `------ Limit 17
; | | | | | `------- Limit 18
; | | | | `-------- Limit 19
; | | | `--------- available for use
; | | `---------- 0 always
; | `----------- size of data. 1 for 32bits
; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko)
db 0x0 ; Base Address 31:24
GDT_LENGTH:
[BITS 16]
disable_cursor:
pushf
push eax
push edx
mov dx, 0x3D4
mov al, 0xA ; low cursor shape register
out dx, al
inc dx
mov al, 0x20 ; bits 6-7 unused, bit 5 disables the cursor, bits 0-4 control the cursor shape
out dx, al
pop edx
pop eax
popf
ret
get_dimensions:
push eax
push ebx
mov ah, 0x0F
int 0x10
mov [VGA_HEIGHT], ah
mov [VIDEO_MODE], al
pop ebx
pop eax
ret
;-----------------------------------------------------------------------;
; Checks if the CPU is compatible with 64-bits operating systems ;
; If the 21th bit of the eax register is set, then CPUID is supported ;
; We then test CPUID's result to see if long mode is supported ;
;-----------------------------------------------------------------------;
Is64bits:
pushfd ; recovering the flags in eax
pop eax
mov ecx, eax
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, ecx
shr eax, 21
and eax, 1 ; magical spell of murta
push ecx
popfd
test eax, eax
jz .NonCompat ; if (CPUID non supporté) goto NonCompat
mov eax, 0x80000000
cpuid
cmp eax, 0x80000001
jb .NonCompat ; if (eax <= 0x80000001) goto NonCompat
mov eax, 0x80000001
cpuid
test edx, 1 << 29
jz .NonCompat ; if (edx != 1 << 29) goto NonCompat
ret ; back to mbr.s
.NonCompat:
stc
ret
;; INCLUDES
%include "boot/common.inc" ; for PrintB
main:
;; compatibility check
mov si, Init
call PrintB
pop si
call Is64bits
jc ErrorNo64
push si
mov si, Pass
call PrintB
;; enabling A20
mov si, EnA20
call PrintB
pop si
in al, 0x92
or al, 2
out 0x92, al
push si
mov si, Pass
call PrintB
;; DISABLING CURSOR BLINKING AND GETTING INFOS
call get_dimensions
call disable_cursor
;;GO GDT64
cli ; disable interrupts
lgdt [GDT64]
;; ACTIVATE PROTECTED MODE
mov eax, cr0
or al, 1b ; PE = 1
mov cr0, eax
;; DISABLE PAGING
mov eax, cr0
and eax, 0x7FFFFFFF ; PG = 0
; |0|111111111111111111111111111111
; |
; `------ Paging bit
mov cr0, eax
push dword [VIDEO_MODE]
push dword [VGA_HEIGHT]
jmp (CODE_SELECTOR-GDT64):main32
[BITS 32]
VIDEO_MODE32 dw 0
VGA_HEIGHT32 dw 0
main32:
pop dword [VGA_HEIGHT32]
pop dword [VIDEO_MODE32]
;; INITIALIZE PROTECTED MODE SEGMENT REGISTERS
mov ax, DATA_SELECTOR-GDT64
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
;; ACTIVATE PHYSICAL ADRESS EXTENSION
mov eax, cr4
or eax, 100000b ; PAE = 1 = 4 Mo / page. 0 = 4 Ko
mov cr4, eax
;;cleanup
mov edi, 0x70000
mov ecx, 0x10000
xor eax, eax
rep stosd
;;formatting
mov dword [0x70000], 0x71000 + 7 ; first PDP table
mov dword [0x71000], 0x72000 + 7 ; first page directory
mov dword [0x72000], 0x73000 + 7 ; first page table
mov edi, 0x73000 ; address of first page table
mov eax, 7
mov ecx, 256 ; number of pages to map (1 MB)
.make_page_entries:
stosd
add edi, 4
add eax, 0x1000
loop .make_page_entries
;; pointing pml4
mov eax, 0x70000 ; Bass address of PML4
mov cr3, eax ; load page-map level-4 base
;; ACTIVATE LONG MODE
mov ecx, 0xC0000080 ; address of MSR
rdmsr ; read MSR
or eax, 100000000b ; LME = 1. (Long Mode Enable)
wrmsr ; write MSR
;; ACTIVATE PAGING
mov eax, cr0
or eax, 0x80000000 ; make bit 31 (PG = Paging) to 1 :
; |1|000000000000000000000000000000
; |
; `------ Paging bit
mov cr0, eax
push dword 0
push dword [VIDEO_MODE]
push dword 0
push dword [VGA_HEIGHT]
jmp (LONG_SELECTOR-GDT64):main64
[BITS 64]
;; FUNCTIONS
write:
;-----------------------------------------------------------------------;
; x64/LM Text Printing Functions ;
; bl : color code ;
; esi : string address ;
;-----------------------------------------------------------------------;
mov edi, [NextTRAM] ;TRAM ADDRESS
push rsi
push rdi
.pLoop:
lodsb
cmp al, 0 ; while @al, i.e. while we're not hitting '\0'
je .pEnd
cmp al, 0x0A ; LF
je .lf
cmp al, 0x0D ; CR
je .cr
stosb ; text subpixel
mov al, bl
stosb ; color subpixel
add qword [NextTRAM], 0x2 ; Cursor moving
add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels
jmp .pLoop
.pEnd:
pop rdi
pop rsi
ret
.lf:
mov rax, [VGA_HEIGHT64]
add [NextTRAM], rax ; Cursor moving
add [NextTRAM], rax
add edi, eax ; Address moving
add edi, eax
jmp .pLoop
.cr:
push rax
mov rax, qword [VGA_X]
sub qword [NextTRAM], rax ; pos = X + Y * VGA_HEIGHT64. Donc pos - X = début de ligne
sub edi, edx
mov qword [VGA_X], 0
pop rax
jmp .pLoop
.scroll:
jmp .pLoop
;; DATA
txt db 0x09, " Switching to Long Mode... OK", 0x0A, 0x0D, 0
Init db 0x09, " Checking CPUID", 0
EnA20 db 0x09, " Enabling A20 line", 0
Pass db " OK", 0x0A, 0x0D, 0
NextTRAM dq 0x0B8AA0 ; Last position of cursor
VIDEO_MODE64 dq 0
VGA_HEIGHT64 dq 0
VGA_X dq 0x0
msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0
main64:
pop qword [VGA_HEIGHT64]
pop qword [VIDEO_MODE64]
;; INITIALIZE STACK
mov rsp, 0x9F000
;; NOTIFYING
mov bl, 0x0A
mov esi, txt
call write
mov bl, 0x0B
mov esi, msg
call write
mov bl, 0x0C
mov esi, msg
call write
mov bl, 0x0D
mov esi, msg
call write
mov bl, 0x0E
mov esi, msg
call write
;call KERNEL
jmp $
[BITS 16]
ErrorNo64:
mov si, NoLongMode
call PrintB
Die:
cli
hlt ; die nooooow
retf
times 1024-($-$$) db 144
KERNEL:

View File

@ -1,26 +0,0 @@
;=----------------------------------------------------------------------------=;
; GNU GPL OS/K ;
; ;
; Authors: spectral` ;
; NeoX ;
; ;
; Desc: Functions for the OS/K mbr ;
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
;-----------------------------------------------------------------------;
; Checks if the CPU is compatible with 64-bits operating systems ;
; If the 21th bit of the eax register is set, then CPUID is supported ;
; We then test CPUID's result to see if long mode is supported ;
;-----------------------------------------------------------------------;

View File

@ -8,121 +8,181 @@
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
[BITS 16] ; real mode
[ORG 0x7C00] ; address where the BIOS/UEFI CSM is loading us
jmp 0x0000:Start ; far-jump to avoid loading address issues with older BIOSes
; some older BIOSes could load bootloader.bin at 0x7C00:0x0000
; while newer ones would load it at 0x0000:0x7C00...
; here the far-jump sets CS to 0
bootdb db 'GNUOS/K ' ;Fabricant + n°série Formatage
sizec dw 512 ;octet/secteur
db 1 ;secteur/cluster
reserv dw 1 ;secteur reserv‚
nbfat db 2 ;nb de copie de la FAT
nbfit dw 224 ;taille rep racine
allclu dw 2880 ;nb secteur du volume si < 32 még
db 0F0h ;Descripteur de média
fatsize dw 9 ;secteur/FAT
nbtrack dw 18 ;secteur/piste
head dw 2 ;nb de tˆteb de lecture/écriture
hidden dd 0 ;nombre de secteur cach‚s
dd 0 ;si nbsecteur = 0 nbsect ; the number of sectors
bootdrv db 0 ;Lecteur de d‚marrage
bootsig db 0 ;NA
db 29h ;boot signature 29h
bootsig2 dd 01020304h ;no de serie
pope db 'COS2000 ' ;nom de volume
db 'FAT12 ' ;FAT
;; DATA
Bootdrv db 0x00
Starting db 0x0A, 0x0D, 0x07, " GNU GPL OS/K ", 0x0A, 0x0D, 0x0A, 0x0D, 0
NoLongMode db 0x0A, 0x0D, "ERROR: Your computer is not designed for x64 OS", 0
A20ERR db 0x0A, 0x0D, "ERROR: Failed to enable A20 line!", 0
SwErr db 0x0A, 0x0D, "ERROR: Loading failed!", 0
Init db 0x09, " Checking CPUID", 0
EnA20 db 0x09, " Enabling A20 line", 0
Switch db 0x09, " Loading Second Stage", 0
Pass db " OK", 0x0A, 0x0D, 0
%define SECOND_STAGE 0x100
;; INCLUDES
%include "boot/mbr.inc" ; for Is64Bits
%include "boot/common.inc" ; for PrintB
[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 "
Start:
;; saving registers for future
pushad
pushfd
pushf
mov [Bootdrv], dl ; dl contains the boot drive. Saving it.
;; dl contains the boot drive. Saving it.
mov [Bootdrv], dl
;; hello world
push si
mov si, Starting
call PrintB
;; compatibility check
mov si, Init
call PrintB
pop si
call Is64bits ; in mbr.inc
jc ErrorNo64
push si
mov si, Pass
call PrintB
;; enabling A20
mov si, EnA20
call PrintB
pop si
in al, 0x92
or al, 2
out 0x92, al
jc A20Fail
push si
mov si, Pass
call PrintB
;; switch to second stage
;; SWITCHING TO LOADER
mov si, Switch
call PrintB
pop si
;; Reset floppy drive and load second stage
call LoadSec ; Loading from boot disk
jc SwFail
mov cx, word [SectorsPerCluster] ; size of a cluster in sectors is stored in cx
; 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
; 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
popf
popfd
popad
mov ax, [Bootdrv]
push ax
jmp dword SECOND_STAGE:0000 ; Jumping to second stage loader.
push word [Bootdrv]
call dword SECOND_STAGE:0000
; Exiting
mov ah, 0x00
int 0x19 ; warm boot computer
;;END OF MBR
;;----------------------------------------------------------------------------;;
A20Fail:
mov si, A20ERR
call PrintB
jmp Die
SwFail:
mov si, SwErr
call PrintB
jmp Die
ErrorNo64:
mov si, NoLongMode
call PrintB
Die:
cli
hlt ; die nooooow
jmp Die
;; 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
End:
times 510-($-$$) db 144 ; NOP until 510
dw 0xAA55 ; magic word
times 510-($-$$) db 144 ; NOP until 510
dw 0xAA55 ; magic word

View File

@ -1,198 +0,0 @@
;=----------------------------------------------------------------------------=;
; GNU GPL OS/K ;
; ;
; Authors: spectral` ;
; NeoX ;
; ;
; Desc: Master Boot Record for OS/K ;
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
%define SECOND_STAGE 0x100
[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 "
Start:
;; saving registers for future
pushad
pushfd
pushf
;; dl contains the boot drive. Saving it.
mov [Bootdrv], dl
;; hello world
push si
mov si, Starting
call PrintB
;; SWITCHING TO LOADER
mov si, Switch
call PrintB
pop si
mov cx, word [SectorsPerCluster] ; size of a cluster in sectors is stored in cx
; 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
; 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
popf
popfd
popad
push word [Bootdrv]
call dword SECOND_STAGE:0000
; Exiting
mov ah, 0x00
int 0x19 ; warm boot computer
;;END OF MBR
;;----------------------------------------------------------------------------;;
;; 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
;; Holes
SwFail:
jmp Die
ErrorNo64:
mov si, NoLongMode
call PrintB
Die:
cli
hlt ; die nooooow
jmp Die
End:
times 510-($-$$) db 144 ; NOP until 510
dw 0xAA55 ; magic word

View File

@ -1,10 +0,0 @@
//----------------------------------------------------------------------------//
// GNU GPL OS/K //
// //
// Authors: spectral` //
// NeoX //
// //
// Desc: Kernel entry point //
//----------------------------------------------------------------------------//

View File

@ -1,13 +0,0 @@
;=----------------------------------------------------------------------------=;
; GNU OS/K ;
; ;
; Authors: spectral` ;
; NeoX ;
; ;
; Desc: Pseudo kernel test for OS/K ;
; (x86_64 architecture only) ;
;=----------------------------------------------------------------------------=;
[BITS 64]
times 1024-($-$$) db 144

View File

@ -1,76 +0,0 @@
#include "types.h"
#define RAMSCREEN 0xB8000 /* debut de la memoire video */
#define SIZESCREEN 0xFA0 /* 4000, nombres d'octets d'une page texte */
#define SCREENLIM 0xB8FA0
char kX = 0; /* position courante du curseur a l'ecran */
char kY = 17;
char kattr = 0x0E; /* attributs video des caracteres a afficher */
/*
* 'scrollup' scrolle l'ecran (la console mappee en ram) vers le haut
* de n lignes (de 0 a 25).
*/
void scrollup(unsigned int n)
{
unsigned char *video, *tmp;
for (video = (unsigned char *) RAMSCREEN;
video < (unsigned char *) SCREENLIM; video += 2) {
tmp = (unsigned char *) (video + n * 160);
if (tmp < (unsigned char *) SCREENLIM) {
*video = *tmp;
*(video + 1) = *(tmp + 1);
} else {
*video = 0;
*(video + 1) = 0x07;
}
}
kY -= n;
if (kY < 0)
kY = 0;
}
void putcar(uchar c)
{
unsigned char *video;
int i;
if (c == 10) { /* CR-NL */
kX = 0;
kY++;
} else if (c == 9) { /* TAB */
kX = kX + 8 - (kX % 8);
} else if (c == 13) { /* CR */
kX = 0;
} else { /* autres caracteres */
video = (unsigned char *) (RAMSCREEN + 2 * kX + 160 * kY);
*video = c;
*(video + 1) = kattr;
kX++;
if (kX > 79) {
kX = 0;
kY++;
}
}
if (kY > 24)
scrollup(kY - 24);
}
/*
* 'print' affiche a l'ecran, a la position courante du curseur, une chaine
* de caracteres terminee par \0.
*/
void print(char *string)
{
while (*string != 0) { /* tant que le caractere est different de 0x0 */
putcar(*string);
string++;
}
}

View File