HDD Bootloader for c++ kernel
HDD Bootloader for c++ kernel
Hello everybody,
I've written a kernel in c++ and i have got a bootloader for a floppy.
However, I know that it wouldn't work on a hard drive, so does anybody know a good site or source for a hdd bootloader? And I use partcopy to write the bootloader to the floppy, but how do I use it for a hdd?
Hope someone can help me!
Daniel
I've written a kernel in c++ and i have got a bootloader for a floppy.
However, I know that it wouldn't work on a hard drive, so does anybody know a good site or source for a hdd bootloader? And I use partcopy to write the bootloader to the floppy, but how do I use it for a hdd?
Hope someone can help me!
Daniel
Re: HDD Bootloader for c++ kernel
If you're using INT 0x13/AH=0x02 for loading sectors, then just change the drive ID and compensate for the differences in cylinder/track/sector per track counts and re-use that same INT. Use INT 0x13/AH=0x08 to get the drive parameters, then use those values later for INT 0x13/AH=0x02.
This will allow you to boot of just about any normal media.
This will allow you to boot of just about any normal media.
Website: https://joscor.com
Re: HDD Bootloader for c++ kernel
This is my bootloader:
I'ts special for floppy's written, so I think I've to write a complete new bootloader..
Code: Select all
[BITS 16]
[ORG 0x0000]
jmp START
OEM_ID db "QUASI-OS"
BytesPerSector dw 0x0200
SectorsPerCluster db 0x01
ReservedSectors dw 0x0001
TotalFATs db 0x02
MaxRootEntries dw 0x00E0
TotalSectorsSmall dw 0x0B40
MediaDescriptor db 0xF0
SectorsPerFAT dw 0x0009
SectorsPerTrack dw 0x0012
NumHeads dw 0x0002
HiddenSectors dd 0x00000000
TotalSectorsLarge dd 0x00000000
DriveNumber db 0x00
Flags db 0x00
Signature db 0x29
VolumeID dd 0xFFFFFFFF
VolumeLabel db "QUASI BOOT"
SystemID db "FAT12 "
START:
cli
mov ax, 0x07C0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x0000
mov ss, ax
mov sp, 0xFFFF
sti
mov si, msgLoading
call DisplayMessage
LOAD_ROOT:
xor cx, cx
xor dx, dx
mov ax, 0x0020
mul WORD [MaxRootEntries]
div WORD [BytesPerSector]
xchg ax, cx
mov al, BYTE [TotalFATs]
mul WORD [SectorsPerFAT]
add ax, WORD [ReservedSectors]
mov WORD [datasector], ax
add WORD [datasector], cx
mov bx, 0x0200
call ReadSectors
mov cx, WORD [MaxRootEntries]
mov di, 0x0200
.LOOP:
push cx
mov cx, 0x000B
mov si, ImageName
push di
rep cmpsb
pop di
je LOAD_FAT
pop cx
add di, 0x0020
loop .LOOP
jmp FAILURE
LOAD_FAT:
mov si, msgCRLF
call DisplayMessage
mov dx, WORD [di + 0x001A]
mov WORD [cluster], dx
xor ax, ax
mov al, BYTE [TotalFATs]
mul WORD [SectorsPerFAT]
mov cx, ax
mov ax, WORD [ReservedSectors]
mov bx, 0x0200
call ReadSectors
mov si, msgCRLF
call DisplayMessage
mov ax, 0x0100
mov es, ax
mov bx, 0x0000
push bx
LOAD_IMAGE:
mov ax, WORD [cluster]
pop bx
call ClusterLBA
xor cx, cx
mov cl, BYTE [SectorsPerCluster]
call ReadSectors
push bx
mov ax, WORD [cluster]
mov cx, ax
mov dx, ax
shr dx, 0x0001
add cx, dx
mov bx, 0x0200
add bx, cx
mov dx, WORD [bx]
test ax, 0x0001
jnz .ODD_CLUSTER
.EVEN_CLUSTER:
and dx, 0000111111111111b
jmp .DONE
.ODD_CLUSTER:
shr dx, 0x0004
.DONE:
mov WORD [cluster], dx
cmp dx, 0x0FF0
jb LOAD_IMAGE
DONE:
mov si, msgCRLF
call DisplayMessage
push WORD 0x0100
push WORD 0x0000
retf
FAILURE:
mov si, msgFailure
call DisplayMessage
mov ah, 0x00
int 0x16
int 0x19
DisplayMessage:
lodsb
or al, al
jz .DONE
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x07
int 0x10
jmp DisplayMessage
.DONE:
ret
ReadSectors:
.MAIN
mov di, 0x0005
.SECTORLOOP
push ax
push bx
push cx
call LBACHS
mov ah, 0x02
mov al, 0x01
mov ch, BYTE [absoluteTrack]
mov cl, BYTE [absoluteSector]
mov dh, BYTE [absoluteHead]
mov dl, BYTE [DriveNumber]
int 0x13
jnc .SUCCESS
xor ax, ax
int 0x13
dec di
pop cx
pop bx
pop ax
jnz .SECTORLOOP
int 0x18
.SUCCESS
mov si, msgProgress
call DisplayMessage
pop cx
pop bx
pop ax
add bx, WORD [BytesPerSector]
inc ax
loop .MAIN
ret
ClusterLBA:
sub ax, 0x0002
xor cx, cx
mov cl, BYTE [SectorsPerCluster]
mul cx
add ax, WORD [datasector]
ret
LBACHS:
xor dx, dx
div WORD [SectorsPerTrack]
inc dl
mov BYTE [absoluteSector], dl
xor dx, dx
div WORD [NumHeads]
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret
absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00
datasector dw 0x0000
cluster dw 0x0000
ImageName db "KERNEL BIN"
msgLoading db 0x0D, 0x0A, "Loading Boot Image ", 0x0D, 0x0A, 0x00
msgCRLF db 0x0D, 0x0A, 0x00
msgProgress db ".", 0x00
msgFailure db 0x0D, 0x0A, "ERROR : Press Any Key to Reboot", 0x00
TIMES 510-($-$$) DB 0
DW 0xAA55
Re: HDD Bootloader for c++ kernel
The FreeDOS project has some open source bootloaders that boot from the hard drive.
They can be found here: http://freedos.cvs.sourceforge.net/view ... rnel/boot/
I use a modified version of boot32lb.asm (Boot via HDD with FAT32) to load my second level loader.
-Ian
They can be found here: http://freedos.cvs.sourceforge.net/view ... rnel/boot/
I use a modified version of boot32lb.asm (Boot via HDD with FAT32) to load my second level loader.
-Ian
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Re: HDD Bootloader for c++ kernel
Thanks for the link!
This is my hdd bootloader now:
As I said, I use partcopy to write the bootloader. Usually, I write it into a floppy, but what about a hdd? What command do I use for that?
This is my hdd bootloader now:
Code: Select all
segment .text
org 0x7c00
Entry: jmp short real_start
nop
; %define bsOemName bp+0x03
%define bsBytesPerSec bp+0x0b
%define bsSecPerClust bp+0x0d
%define bsResSectors bp+0x0e
%define bsFATs bp+0x10
; %define bsRootDirEnts bp+0x11
; %define bsSectors bp+0x13
; %define bsMedia bp+0x15
; %define sectPerFat bp+0x16
%define sectPerTrack bp+0x18
; %define nHeads bp+0x1a
%define nHidden bp+0x1c
; %define nSectorHuge bp+0x20
%define xsectPerFat bp+0x24
%define xrootClst bp+0x2c
%define drive bp+0x40
%define loadsegoff_60 bp+loadseg_off-Entry
%define LOADSEG 0x0060
%define FATSEG 0x2000
%define fat_secshift fat_afterss-1
%define fat_sector bp+0x44
%define fat_start bp+0x48
%define data_start bp+0x4c
times 0x5a-$+$$ db 0
real_start: cld
cli
sub ax, ax
mov ds, ax
mov bp, 0x7c00
mov ax, 0x1FE0
mov es, ax
mov si, bp
mov di, bp
mov cx, 0x0100
rep movsw
jmp word 0x1FE0:cont
loadseg_off dw 0, LOADSEG
cont: mov ds, ax
mov ss, ax
lea sp, [bp-0x20]
sti
mov [drive], dl
mov si, msg_LoadFreeDOS
call print
calc_params: xor eax, eax
mov [fat_sector], eax
mov ax, [bsResSectors]
add eax, [nHidden]
mov [fat_start], eax
mov [data_start], eax
mov eax, [bsFATs]
imul dword [xsectPerFat]
add [data_start], eax
mov ax, 512
; mov cl, 9-2
fatss_scan: cmp ax, [bsBytesPerSec]
jz fatss_found
add ax,ax
; inc cx
inc word [fat_secshift]
jmp short fatss_scan
fatss_found:
mov eax, [xrootClst]
ff_next_clust: push eax
call convert_cluster
jc boot_error
ff_next_sector: les bx, [loadsegoff_60]
call readDisk
; push eax
; xor ax, ax
xor di, di
ff_next_entry: mov cx, 11
mov si, filename
; mov di, ax
repe cmpsb
jz ff_done
; add ax, 0x20
;cmp ax, [bsBytesPerSec]
add di, byte 0x20
and di, byte -0x20
cmp di, [bsBytesPerSec]
jnz ff_next_entry
; pop eax
dec dx
jnz ff_next_sector
ff_walk_fat: pop eax
call next_cluster
jmp ff_next_clust
ff_done: push word [es:di+0x14-11]
push word [es:di+0x1A-11]
pop eax
sub bx, bx
read_kernel: push eax
call convert_cluster
jc boot_success
rk_in_cluster: call readDisk
dec dx
jnz rk_in_cluster
rk_walk_fat: pop eax
call next_cluster
jmp read_kernel
boot_success: mov bl, [drive]
jmp far [loadsegoff_60]
boot_error: mov si, msg_BootError
call print
wait_key: xor ah,ah
int 0x16
reboot: int 0x19
next_cluster: push es
push di
push bx
mov di, ax
shl di, 2
push ax
mov ax, [bsBytesPerSec]
dec ax
and di, ax
pop ax
shr eax, 7
fat_afterss:
add eax, [fat_start]
mov bx, FATSEG
mov es, bx
sub bx, bx
cmp eax, [fat_sector]
jz cn_buffered
mov [fat_sector],eax
call readDisk
cn_buffered: and byte [es:di+3],0x0f
mov eax, [es:di]
pop bx
pop di
pop es
ret
convert_cluster:
cmp eax, 0x0ffffff8
jnb end_of_chain
; sector = (cluster-2) * clustersize + data_start
dec eax
dec eax
movzx edx, byte [bsSecPerClust]
push edx
mul edx
pop edx
add eax, [data_start]
ret
end_of_chain: stc
ret
printchar: xor bx, bx
mov ah, 0x0e
int 0x10
print: lodsb
cmp al, 0
jne printchar
ret
readDisk: push dx
push si
push di
read_next: push eax
mov di, sp
; db 0x66
push byte 0
push byte 0
push eax
push es
push bx
push byte 1
push byte 16
mov si, sp
mov dl, [drive]
mov ah, 42h
int 0x13
mov sp, di
pop eax
jnc read_ok
push ax
xor ah, ah
int 0x13
pop ax
jmp read_next
read_ok: inc eax
add bx, word [bsBytesPerSec]
jnc no_incr_es
mov dx, es
add dh, 0x10
mov es, dx
no_incr_es: pop di
pop si
pop dx
ret
msg_LoadFreeDOS db "Loading Thunder Core",0
times 0x01ee-$+$$ db 0
msg_BootError db "No "
filename db "KERNEL BIN"
sign dw 0, 0xAA55
Re: HDD Bootloader for c++ kernel
Wow. Two bootloader source dumps without a single comment line.
Every good solution is obvious once you've found it.
-
- Member
- Posts: 93
- Joined: Mon Nov 24, 2008 9:13 am
Re: HDD Bootloader for c++ kernel
That's not true, have a closer look:Solar wrote:Wow. Two bootloader source dumps without a single comment line.
Code: Select all
[...]
; %define bsRootDirEnts bp+0x11
; %define bsSectors bp+0x13
; %define bsMedia bp+0x15
; %define sectPerFat bp+0x16
[...]
Sorry, couldn't resist...
--TS
Re: HDD Bootloader for c++ kernel
I've removed the comments, because if i didn't, it would be a VERY long code! And I wrote it in Notepad++ where u can see the difference in comment and normal color because of the colors. As u can see, it's all green what makes it obscure.Solar wrote:Wow. Two bootloader source dumps without a single comment line.
BTW, I'm testing my OS on my formatted laptop, so there's no single bootloader/MBR. I've been thinking: If I only put a single bootloader in the first partition, and there's no MBR, how can it boot??? Not. Can anyone help me with writing a MBR (or u have a good source)? It would be very nice!
Re: HDD Bootloader for c++ kernel
I've got a MBR now and I use partcopy to write the bootloaders. I know how to do with floppies and normal partitions, but what about the MBR? How do I write it with partcopy? Or do I have to use another one?
Re: HDD Bootloader for c++ kernel
How can I do it with dd? BTW: I put the floppy in my laptop and THEN I write everything (bootloader, kernel,etc.). Is it possible to use dd on a floppy?