I want to do a simple bootloader from scratch. I want it to be able to boot on usb on a recent laptop, meaning it has UEFI boot but theoretically it supports Legacy boot.
So I wrote a little assembly code, which just prints "hello world", and compiled it with nasm -f bin boot.asm -o boot.com Then I built the diskette from the binary with dd. The diskete worked fine with qemu-system-x86_64. I transfered it to the MBR of a usb stick formatted as FAT32 using dd if=boot.bin of=/dev/sda. But when booting on it with my recent computer, the usb doesn't show up in the bootable devices.
I tried to : - boot it on Qemu (with qemu-system-x86_64 -hdb /dev/sda) successfully - boot it on a really old computer with a intel Pentium 4 processor and everything worked as expected. - enable legacy mode in the bios options - disable secure boot - boot it on another computer, where the usb stick shows up in bootable devices, but nothing is printed.
I found it on internet, so the assembly should be correct
;; A tiny, working bootloader for x86 PCs. Has a few subroutines
;; so it's slightly less useless than just printing "hello world".
;;
;; writeup here: http://joebergeron.io/posts/post_two.html
;;
;; Joe Bergeron, 2016.
;;
bits 16
mov ax, 07C0h
mov ds, ax
mov ax, 07E0h ; 07E0h = (07C00h+200h)/10h, beginning of stack segment.
mov ss, ax
mov sp, 2000h ; 8k of stack space.
call clearscreen
push 0000h
call movecursor
add sp, 2
push msg
call print
add sp, 2
cli
hlt
clearscreen:
push bp
mov bp, sp
pusha
mov ah, 07h ; tells BIOS to scroll down window
mov al, 00h ; clear entire window
mov bh, 07h ; white on black
mov cx, 00h ; specifies top left of screen as (0,0)
mov dh, 18h ; 18h = 24 rows of chars
mov dl, 4fh ; 4fh = 79 cols of chars
int 10h ; calls video interrupt
popa
mov sp, bp
pop bp
ret
movecursor:
push bp
mov bp, sp
pusha
mov dx, [bp+4] ; get the argument from the stack. |bp| = 2, |arg| = 2
mov ah, 02h ; set cursor position
mov bh, 00h ; page 0 - doesn't matter, we're not using double-buffering
int 10h
popa
mov sp, bp
pop bp
ret
print:
push bp
mov bp, sp
pusha
mov si, [bp+4] ; grab the pointer to the data
mov bh, 00h ; page number, 0 again
mov bl, 00h ; foreground color, irrelevant - in text mode
mov ah, 0Eh ; print character to TTY
.char:
mov al, [si] ; get the current char from our pointer position
add si, 1 ; keep incrementing si until we see a null char
or al, 0
je .return ; end if the string is done
int 10h ; print the character if we're not done
jmp .char ; keep looping
.return:
popa
mov sp, bp
pop bp
ret
msg: db "Oh boy do I sure love assembly!", 0
times 510-($-$$) db 0
dw 0xAA55
I want to be able to boot the usb on my recent computer, running a i7-8550U processor and UEFI/Legacy compatible. For the moment, the usb stick doesn't show up in bootable devices.
EDIT : Thank you for your replies ! I tried to set the Bios Parameter Block (BPB) by adding this piece of code :
ORG 0
BITS 16
jmp near start
db "MYBOOT "
dw 512
db 1
dw 1
db 2
dw 512
dw 65535
db 0xf8
dw 20
dw 63
dw 16
dd 0
dd 0
db 0x29
dd 0xffff
db 0
db 0
db "NO NAME "
db "FAT32 "
start:
blablabla (see above)
and the usb stick now shows up on the ubuntu desktop (I noticed that it disapear if I use something else than 'jmp near start' like 'jmp short start') But it still doesn't want to appear in my bios boot menu.. I really don't know why it doesn't want to see it at this point. I have Bios version F.23, maybe there is a special way to do it with this bios ?