Reputation: 11
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 ?
Upvotes: 1
Views: 676
Reputation: 47633
I can't place this in a comment, and I will amend this to be a proper answer if any of this helps. The code provided MAY actually be a solution to the problem too. This is based on a similar set of circumstances with a newer BIOS as was discovered on OSDev Forum discussion a number of months ago.
Can you try to compile and build an MBR using this and see if your BIOS recognizes the drive as bootable? It contains a self-referencing partition table if you happen to be booting on partitioned media. Not sure what USB media your BIOS is emulating and wish to have you simply test this out to see if it prints:
Hello, world!
The code:
bits 16
org 0x7c00
boot_start:
xor ax, ax ; DS=0 since we use ORG 0x7c00. 0x0000<<4+0x7c00=0x7c00
mov ds, ax
mov es, ax
; If you will be reading data into memory outside of 0x7c00 to 0x7dff
; then you want to set the stack SS:SP - uncomment these lines
; mov ss, ax ; Stack at 0x0000:0x7c00
; mov sp, 0x7c00 ; Just below bootloader
cld ; Forward movement of string instructions
; (MOVSB, SCASB, etc)
mov si, HelloWorldMsg ; Print hello world
call print_string
end_loop: ; Loop forever to terminate
hlt
jmp end_loop
; Function: print_string
; Display a string to the console on display page 0
;
; Inputs: SI = Offset of address to print
; Clobbers: AX, BX, SI
print_string:
mov ah, 0x0e ; BIOS tty Print
xor bx, bx ; Set display page to 0 (BL)
jmp .getch
.repeat:
int 0x10 ; print character
.getch:
lodsb ; Get character from string
test al,al ; Have we reached end of string?
jnz .repeat ; if not process next character
.end:
ret
HelloWorldMsg: db "Hello, world!", 0x0d, 0x0a, 0
times 446-($-$$) db 0 ; Pad with 0s up until first partition entry
part1_entry:
db 0x80 ; 0x80 = Active boot partition, 0x00=inactive
db 0x00, 0x01, 0x00 ; CHS of first absolute sector (MBR) of hard drive
; Head=0, Sector=1, Cylinder=0
db 0x0c ; Partition type (has to be non-zero)
; 0x0c = Win 95 FAT32 (LBA)
db 0x00, 0x01, 0x00 ; CHS of last absolute sector (MBR) of hard drive
; Head=0, Sector=1, Cylinder=0
; We are effectively saying Size of partition is 1 sector
dd 0x0 ; LBA of first absolute sector (0=MBR)
dd 0x1 ; Number of sectors in partition. We set it to 1 but if you
; wish you could set it to the number of sectors on the disk
times 510-($-$$) db 0 ; Pad remainder of boot sector up to boot signature. This zeroes
; partition entries 2,3,4 effectively making them inactive
dw 0xAA55 ; The standard PC boot signature after partition table
This code may not make your drive visible or even boot and output anything, however the results can help narrow down the problem space. Part of me thinks there is a possibility that there is more than just a BPB issue given how your BIOS is reacting.
Upvotes: 1