Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 546 Vote(s) - 3.54 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to produce a minimal BIOS hello world boot sector with GCC that works from a USB stick on real hardware?

#1
I have managed to produce a minimal boot sector that works with QEMU 2.0.0 Ubuntu 14.04:

.code16
.global _start
_start:
cli
mov $msg, %si
mov $0x0e, %ah
loop:
lodsb
or %al, %al
jz halt
int $0x10
jmp loop
halt:
hlt
msg:
.asciz "hello world"
.org 510
.word 0xaa55

Compiled with:

as -o main.o main.S
ld --oformat binary -o main.img -Ttext 0x7C00 main.o

The example is available on this repo:

[To see links please register here]


Upon:

qemu -hda main.img

it shows `hello world` on the emulator screen as expected.

But if I try to burn to a USB:

sudo dd if=main.img of=/dev/sdb

then plug the USB into a ThinkPad T400 or T430, hit F12, and select the USB what I observe is:

- some boot messages show up quickly
- then the screen goes blank, with only a underscore cursor at the top

I have also tested the same USB with a Ubuntu 14.04 image, and it booted fine, so the USB is working.

How should I change this example so that it will boot on the hardware and show the hello world message?

What is the difference between the Ubuntu image and the one I've created?

Where is this documented?

I have uploaded the output of `sudo dmidecode` on the T400 to: <https://gist.github.com/cirosantilli/d47d35bacc9be588009f#file-lenovo-t400>
Reply

#2
As mentioned by @Jester, I had to zero `DS` with:

@@ -4,2 +4,4 @@ _start:
cli
+ xor %ax, %ax
+ mov %ax, %ds
mov $msg, %si

Note that it is not possible to `mov` immediates to `ds`: we must pass through `ax`:

[To see links please register here]


So the root of the problem was difference between QEMU's initial state and that of the real hardware.

I am now adding the following 16-bit initialization code to all my bootloaders to guarantee a cleaner initial state. Not all of those are mandatory as mentioned by Michael Petch on the comments.

.code16
cli
/* This sets %cs to 0. TODO Is that really needed? */
ljmp $0, $1f
1:
xor %ax, %ax
/* We must zero %ds for any data access. */
mov %ax, %ds
/* The other segments are not mandatory. TODO source */
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
/*
TODO What to move into BP and SP?

[To see links please register here]

Setting BP does not seem mandatory for BIOS.
*/
mov %ax, %bp
/* Automatically disables interrupts until the end of the next instruction. */
mov %ax, %ss
/* We should set SP because BIOS calls may depend on that. TODO confirm. */
mov %bp, %sp

I have also found this closely related question:

[To see links please register here]


The [Intel Manual Volume 3 System Programming Guide - 325384-056US September 2015]( ) 9.10.2 "STARTUP.ASM Listing
" contains a large initialization example.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through