[SOLVED]I might just need the best bootloader in the world..
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
[SOLVED]I might just need the best bootloader in the world..
Hello everybody, I am in a bit of a pickle. I need a bootloader that will load a filesystem(I don't care which) and then load a file called kernel.bin. Kernel.bin will expect to be in 32-bit mode so that is another problem. Is this even possible? -bashcommando
Last edited by bashcommando on Wed Jan 21, 2015 7:38 pm, edited 1 time in total.
Re: I might just need the best bootloader in the world...
I wonder if you've never heard about GRUB and multiboot specification. I think that these things are enough for your needs (including the 32-bit mode).
You can start here: http://wiki.osdev.org/Multiboot
> that will load a filesystem (I don't care which)
What did you mean by this?
Did you mean that bootloader should load some image of filesystem (i.e. initramfs/initrd) ? GRUB is able to do it.
Or did you mean that it should load kernel.bin _from_ some filesystem? Of course it's possible, that's one of key features of loaders.
You can start here: http://wiki.osdev.org/Multiboot
> that will load a filesystem (I don't care which)
What did you mean by this?
Did you mean that bootloader should load some image of filesystem (i.e. initramfs/initrd) ? GRUB is able to do it.
Or did you mean that it should load kernel.bin _from_ some filesystem? Of course it's possible, that's one of key features of loaders.
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
Re: I might just need the best bootloader in the world...
I want to make my own. Maybe I can reverse engineer grub? Obviously I would need GDT to go into 32-bit mode, but I can't figure that out. I didn't care about the filesystem because I was worried that I would pass the 512 bytes limit. Yep, I want kernel.bin loaded from a filesystem, it is coded in complete i686 binary. I have seen projects like MikeOS and stuff like that but can't figure out how they call 32-bit binaries from assembly.Nable wrote:I wonder if you've never heard about GRUB and multiboot specification. I think that these things are enough for your needs (including the 32-bit mode).
You can start here: http://wiki.osdev.org/Multiboot
> that will load a filesystem (I don't care which)
What did you mean by this?
Did you mean that bootloader should load some image of filesystem (i.e. initramfs/initrd) ? GRUB is able to do it.
Or did you mean that it should load kernel.bin _from_ some filesystem? Of course it's possible, that's one of key features of loaders.
Building an operating system is like building an airplane, you don't want it to crash.
Re: I might just need the best bootloader in the world...
Hi,
Also note that I define "best boot loader in the world" quite differently (e.g. boot loader is only the first part of a "multi-stage" process, where other stages do a significant amount of work before the kernel is needed).
Cheers,
Brendan
Are you sure you meant "a bootloader that will load a filesystem"? Typically you'd leave the file system on disk and wouldn't try to load several TiB of data into several GiB of RAM...bashcommando wrote:Hello everybody, I am in a bit of a pickle. I need a bootloader that will load a filesystem(I don't care which) and then load a file called kernel.bin. Kernel.bin will expect to be in 32-bit mode so that is another problem. Is this even possible? -bashcommando
Also note that I define "best boot loader in the world" quite differently (e.g. boot loader is only the first part of a "multi-stage" process, where other stages do a significant amount of work before the kernel is needed).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: I might just need the best bootloader in the world...
Curb your ambition a little. If you are unable to figure out the GDT, how it works, and what the entries in it mean then you are not going to be able to write a bootloader that will load and run a 32-bit kernel. It's fine as a long-term ambition but you need to understand what you are doing first. There is a host of information on the web to help with this. And you could do worse than reading the Intel Programmers Manuals.I want to make my own. Maybe I can reverse engineer grub? Obviously I would need GDT to go into 32-bit mode, but I can't figure that out.
I would start by writing a simple kernel that is loaded by Grub. Resources on this Wiki show you how to do that.
Re: I might just need the best bootloader in the world...
I find it kind of paradoxical that you are looking for a bootloader that does it all for you,
and yet don't want to use GRUB because you "want ot do it yourself".
Anyway, here's one I wrote years ago, where I basically managed to cram in FAT12 loading,
A20 setting & Pmode into one. For obvious reasons, this isn't really a good idea - error
handling is basically non-existent.
and yet don't want to use GRUB because you "want ot do it yourself".
Anyway, here's one I wrote years ago, where I basically managed to cram in FAT12 loading,
A20 setting & Pmode into one. For obvious reasons, this isn't really a good idea - error
handling is basically non-existent.
Code: Select all
;------------------------------------------------------------;
; BOS - FAT12 bootsector ;
;------------------------------------------------------------;
; - FAT12 compatible. ;
; - Loads a binary file from the floppy, max ~576kb. ;
; - Sets A20 and protected mode. ;
; ;
; Thanks to: Petroff Heroj and John S. Fine for examples. ;
; ;
; by: Christoffer Bubach, 2003-2005 ;
; ;
;------------------------------------------------------------;
; other notes:
; this code is public domain, and you can use it for
; anything you want. but if you do, please act polite and
; give credit. ;-)
;
; mem map
; 0x0000:0x0000 -> 0x0000:0x0500 BIOS stuff
; 0x0000:0x0500 -> 0x0000:0x2100 root
; 0x0000:0x2100 -> 0x0000:0x3300 fat
; 0x0000:0x3300 -> 0x0000:0x7c00 18,25kb free space
; 0x0000:0x7c00 -> 0x0000:0x7e00 bootsector
; 0x0000:0x7e00 <- 0x0000:0xffff 32,5kb stack
; 0x1000:0x0000 -> 0x9000:0xffff 576kb free space
; 0xa000:0x0000 -> ............. VGA mem etc.
use16
org 0x7C00
boot: jmp near start
nop
;------------------------------------------;
; Standard BIOS Parameter Block, "BPB". ;
;------------------------------------------;
bpbOEM db 'BOS 0.03'
bpbSectSize dw 512
bpbClustSize db 1
bpbReservedSec dw 1
bpbFats db 2
bpbRootSize dw 224
bpbTotalSect dw 2880
bpbMedia db 240
bpbFatSize dw 9
bpbTrackSect dw 18
bpbHeads dw 2
bpbHiddenSect dd 0
bpbLargeSect dd 0
;---------------------------------;
; extended BPB for FAT12/FAT16 ;
;---------------------------------;
bpbDriveNo db 0
bpbReserved db 0
bpbSignature db 0 ; 0 = nothing more. 41 = three more (below)..
; bpbID dd 1
; bpbVolumeLabel db 'BOOT FLOPPY'
; bpbFileSystem db 'FAT12 '
;----------------------------------------;
; starting point of bootsector code ;
;----------------------------------------;
start:
cli
xor ax, ax ; initialize all the necessary
mov ds, ax ; registers.
mov es, ax
mov ss, ax
mov sp, 0xFFFF ; Stack..
mov [bpbDriveNo], dl
sti
;----------------------------------;
; clear screen and print some ;
;----------------------------------;
mov ax, 3 ; Set mode 0x03
int 0x10
mov bp, loading ; Print loading message.
mov ax, 0x1301
mov bx, 7
mov cx, 12
mov dx, 0x0102
int 0x10
mov bl, 2 ; Set cursor.
mov ah, 2
mov dx, 0x0201
int 0x10
mov ah, 9 ; Print 14 green dots.
mov al, '.'
mov cx, 14
int 0x10
;---------------------------;
; load FAT and root ;
;---------------------------;
mov di, 0x0050 ; Load the root to
mov ax, 19 ; 0x0000:0x0500 (0x500/0x10)
mov cx, 14
call read_sectors
mov di, 0x0210 ; Load the fat to
mov ax, 1 ; 0x0000:0x2100
mov cx, 9
call read_sectors
;------------------------;
; search for the file ;
;------------------------;
mov dx, [bpbRootSize]
mov bx, 0x0500
filesearch:
cld
mov si, filename
mov cx, 11
mov di, bx
repe cmpsb
je found
add bx, 32
dec dx
jz error
jmp filesearch
;-----------------------------------;
; variables & functions ;
;-----------------------------------;
loading db 'Starting BOS'
filename db 'KERNEL SYS'
failure db 'Read error!'
a20_on db 1
;-----------------------------------------------;
; read a number of sectors (one at a time) ;
;-----------------------------------------------;
; in: ;
; di = segment to save at ;
; ax = sector to read ;
; cx = number of sectors ;
; out: ;
; di = updated (added for next read) ;
; ax = updated (added for next read) ;
;-----------------------------------------------;
read_sectors:
pusha
mov bl, byte [bpbTrackSect] ; bl = number of sectors per track
div bl ; al = ax / bl
mov cl, ah ; cl = real sector number
add cl, 1
xor ah, ah ; del the rest of the div before
mov bl, byte [bpbHeads] ; bl = number of heads
div bl ; ah = rest of ( ax / bx ), al = ax / bx
mov ch, al ; ch = number of track
mov dh, ah ; dh = the head number
mov ax, cx ; save cx in ax
mov cx, 6 ; try it 6 times
.next_try:
push es
push cx
mov cx, ax ; restore cx
push cx
xor ax, ax
mov dl, [bpbDriveNo] ; reset drive
push dx
int 0x13
jc .failed
pop dx
pop cx
xor bx, bx
mov es, di
mov ax, 0x0201 ; function 2, 1 sector
int 0x13
jnc .ok ; if it was ok, check next..
.failed:
pop dx
pop ax
pop cx
pop es
loop .next_try ; else try once again if there is an error
jmp error ; if cx = 0 and the read operation always failed, halt
.ok:
pop cx ; from the next_try loop
pop es
popa
add di, 32 ; add 32 (512/16) to segment
inc ax ; add sector counter
loop read_sectors
ret
;----------------------------------------------------;
; show a message and wait for a key before reboot ;
;----------------------------------------------------;
error:
;push 0x0000
;pop es
mov bp, failure
mov ax, 0x1301
mov bx, 4
mov cx, 43
mov dx, 0x0401
int 0x10
mov ah, 0
int 0x16
int 0x19
;-----------------------------------;
; the file is found, load it. ;
;-----------------------------------;
found:
mov bp, [bx+26] ; bp=cluster number from directory entry
mov di, 0x1000 ; 1000 (segment)
.next_block:
xor cx, cx
mov cl, [bpbClustSize] ; reset sector count to 1 cluster
mov si, bp ; si=next should-be cluster for
; contiguous reads
.next_contiguous:
mov ax, 3 ; 3
mul si ; multiply cluster number by 3
; dx assumed to be 0, it's a floppy!
shr ax, 1 ; divide by two
push bp
xchg bp, ax ; bp=ax
mov ax, word [0x2100+bp] ; ax=FAT element with junk
; (addressing with bp)
pop bp
jc byte .odd_cluster ; jump if the value was odd
.even_cluster:
and ax, 0x0FFF ; leave only lower 12 bits
jmp .got_cluster ; got it
.odd_cluster:
push cx ; preserve sector count
mov cl, 4 ; shift four bits right
shr ax, cl ; (leave only bits 4-15)
pop cx ; restore sector count
.got_cluster:
inc si ; si=current cluster+1
cmp ax, si ; next cluster=current cluster+1?
jne byte .force_read ; is it still contiguous?
add cl, [bpbClustSize] ; increase sector count by 1 cluster
adc ch, 0
jmp .next_contiguous
.force_read:
xchg bp, ax ; ax=bp (base cluster), bp=new cluster
dec ax ; decrease by 2 to get the actual... (1)
dec ax ; ...cluster number (2)
xor dx, dx
mov dl, [bpbClustSize]
mul dx ; multiply by sectors per cluster
; (dx ignored)
add ax, 33 ; assume data-area start at sector 33
call read_sectors ; read cx sectors at ax to es:0 :)
cmp bp, 0x0FF8 ; the new cluster is EOF (FF8-FFF)?
jb byte .next_block ; if not in this range, read next block
;-----------------------;
; the file is loaded ;
;-----------------------;
quit:
a20: ; Enable A20
in al, 0x64
test al, 2
jnz a20
mov al, 0xD1
out 0x64, al
.d6:
in al, 0x64
and ax, 2
jnz .d6
mov al, 0xDF
out 0x60, al
.a20_check:
mov al, byte [fs:0] ; check a20, is it on?
mov ah, al
not al
xchg al, byte [gs:0x10]
cmp ah, byte [fs:0]
mov [gs:0x10], al
jz floppy_off
mov [a20_on], 0 ; it's not on save for file..
floppy_off:
mov dx, 0x3F2 ; turn of the floppy motor.
mov al, 0
out dx, al
pmode:
cli ; set protected mode (32-bit)
lgdt [gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 0x08:flush
;----------------------------------------;
; start of 32-bit area. ;
; flush segments and jump to kernel ;
;----------------------------------------;
use32
flush:
mov eax, 0x10 ; refresh all segment registers
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov ss, eax
mov esp, 0xfffc
mov eax, 0xB05B007 ; report "BOSboot".. ;-)
mov bl, [a20_on] ; report if a20 is on.
jmp 0x08:0x10000 ; jump to loaded file (64kb in mem)
;--------------------------------;
; global descriptor table (gdt) ;
;--------------------------------;
gdt: dw 0x0000, 0x0000, 0x0000, 0x0000
codesel: dw 0xFFFF, 0x0000, 0x9800, 0x00CF
datasel: dw 0xFFFF, 0x0000, 0x9200, 0x00CF
gdt_end:
gdtr: dw gdt_end - gdt - 1
dd gdt
;-------------------------------------;
; set the BOOT-signature at byte 510. ;
;-------------------------------------;
rb boot+512-2-$
dw 0xAA55
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
Re: I might just need the best bootloader in the world...
Oh thanks, that looks great!bubach wrote:I find it kind of paradoxical that you are looking for a bootloader that does it all for you,
and yet don't want to use GRUB because you "want ot do it yourself".
Anyway, here's one I wrote years ago, where I basically managed to cram in FAT12 loading,
A20 setting & Pmode into one. For obvious reasons, this isn't really a good idea - error
handling is basically non-existent.
Last edited by bashcommando on Tue Jan 20, 2015 1:59 pm, edited 2 times in total.
Building an operating system is like building an airplane, you don't want it to crash.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: I might just need the best bootloader in the world...
Looks like you haven't even learned how to properly copy-paste. Do we need to put that in the required knowledge as well?bashcommando wrote:Code: Select all
300 nasm errors, roughly one for each line
(There should be one error, only because RB isn't nasm-proof.)
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
Re: I might just need the best bootloader in the world...
I might have deleted a line by mistake or something. Lesson learned.Combuster wrote:Looks like you haven't even learned how to properly copy-paste. Do we need to put that in the required knowledge as well?
(There should be one error, only because RB isn't nasm-proof.)
Last edited by bashcommando on Tue Jan 20, 2015 1:56 pm, edited 1 time in total.
Building an operating system is like building an airplane, you don't want it to crash.
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
Re: I might just need the best bootloader in the world...
Oh by the way, can the rb line be replaced with times? Besides you realize some lines are commented, without editing it shows one error. (the rb line)Combuster wrote:Looks like you haven't even learned how to properly copy-paste. Do we need to put that in the required knowledge as well?
(There should be one error, only because RB isn't nasm-proof.)
Building an operating system is like building an airplane, you don't want it to crash.
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
Re: I might just need the best bootloader in the world...
No seriously what does rb do? It looks kind of like times but what do I replace it with? I looked it up and nothing. No opcodes relating to rb?Combuster wrote:Looks like you haven't even learned how to properly copy-paste. Do we need to put that in the required knowledge as well?
(There should be one error, only because RB isn't nasm-proof.)
Building an operating system is like building an airplane, you don't want it to crash.
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: I might just need the best bootloader in the world...
RB is the FASM equivalent of NASM's resb. It basically stands for "reserve bytes". It is same as "times db X" but it leaves the region uninitialized, not even random numbers, it is left as nothing. It usually is used for page alignment, declaring data in the BSS and stuff like that. In this case however, it's same as "times db" since there's data (0xAA55) after the reserved region, which makes the assembler place 0's (hopefully) in there.bashcommando wrote:No seriously what does rb do? It looks kind of like times but what do I replace it with? I looked it up and nothing. No opcodes relating to rb?Combuster wrote:Looks like you haven't even learned how to properly copy-paste. Do we need to put that in the required knowledge as well?
(There should be one error, only because RB isn't nasm-proof.)
And here's the official reference: http://www.nasm.us/doc/nasmdoc3.html
EDIT: I just realised that the mechanism may differ between formats. But since this is binary it should be pretty okay.
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
Re: I might just need the best bootloader in the world...
So in this case do I replace rb with resb?Bender wrote:RB is the FASM equivalent of NASM's resb. It basically stands for "reserve bytes". It is same as "times db X" but it leaves the region uninitialized, not even random numbers, it is left as nothing. It usually is used for page alignment, declaring data in the BSS and stuff like that. In this case however, it's same as "times db" since there's data (0xAA55) after the reserved region, which makes the assembler place 0's (hopefully) in there.
And here's the official reference: http://www.nasm.us/doc/nasmdoc3.html
EDIT: I just realised that the mechanism may differ between formats. But since this is binary it should be pretty okay.
Building an operating system is like building an airplane, you don't want it to crash.
Re: I might just need the best bootloader in the world...
It probably would have taken you less time to try that for yourself then to come here and ask us..... Also I forgot to mention that I used fasm but if the padding code to make it 512 bytes is the only thing that keeps you from using nasm... and you can't even find a nasm bootloader to copy the syntax from? You might be beyond all hope of ever getting somewhere. Sorry.
- bashcommando
- Member
- Posts: 62
- Joined: Mon Jan 06, 2014 4:23 pm
Re: I might just need the best bootloader in the world...
Earlier I found the MikeOS bootloader which does everything but load 32-bit mode. Why didn't you say you used fasm? That would have made my life easier but I learned something from it. I am not hopeless, I have much to learn.bubach wrote:It probably would have taken you less time to try that for yourself then to come here and ask us..... Also I forgot to mention that I used fasm but if the padding code to make it 512 bytes is the only thing that keeps you from using nasm... and you can't even find a nasm bootloader to copy the syntax from? You might be beyond all hope of ever getting somewhere. Sorry.
Building an operating system is like building an airplane, you don't want it to crash.