"Hello world" bootstrap works only on 2 of 3 PCs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Kolodez
Posts: 9
Joined: Wed Jul 27, 2016 5:37 am

"Hello world" bootstrap works only on 2 of 3 PCs

Post by Kolodez »

Hello! Maybe one of you has an idea why my bootstrap code works only on 2 of 3 PCs I've tested it on. On two of them, "Hello, world!" is printed, as I would expect, but on the third one, nothing is printed.

I've already tested the most simple bootstrap ever, namely just "int 0x10" with AX=0x0E21 and BX=0x0007. This worked on all PCs.

This is the assembler code of my bootloader, which works only on 2 of 3 PCs. What am I doing wrong? Maybe a race condition with some handler or some register not set properly? (My final aim is not to write a "hello world" bootstrap code, but something more complex for this one PC where it is not working. So I need to understand the issue and not just to make this "hello world" here working.) Thanks for your help?

Code: Select all

    cli
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov ds, ax
    mov fs, ax
    mov gs, ax
    mov sp, ax
    sti
    push hello ; this is the address (0x7C34) which points to the string location
    call print_string
hang:
    jmp hang

print_string:
    push bp
    mov bp, sp
loop:
    mov bx, [bp + 4]
    mov al, [bx]
    test al, al
    jz break
    mov ah, 0x0E
    mov bx, 0x0007
    push bp ; I've read that some BIOSes have the bug to change bp after interrupt 0x10
    int 0x10
    pop bp
    inc [bp + 4]
    jmp loop
break:
    pop bp
    ret
Below, I also attach the corresponding 512 bytes if anyone has the suspition that I translated something wrong:

Code: Select all

FA 33 C0 8E C0 8E D0 8E D8 8E E0 8E E8 89 C4 FB 68 34 7C E8 02 00 EB FE 55 89 E5 8B 5E 04 8A 07 84 C0 74 0E B4 0E BB 07 00 55 CD 10 5D FF 46 04 EB E9 5D C3 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by SpyderTL »

You have no way of knowing what address and segment that your BIOS used to start your boot loader code, so you have to do a far jump to a specific label before you can safely reference any other labels, like "hello".

Try something like

Code: Select all

jmp far start
start:
Also, you have to tell the compiler where this code will be located:

Code: Select all

org 7c00
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by alexfru »

Is the third PC at least a 386 (you're using FS and GS)? Other than that I can only see two minor issues:
* it starts with CS:IP=0x7C0:0 instead of CS:IP=0:0x7C00, which should be fine for the presented code, but you can force CS:IP to the desired value by doing a far return or an absolute far jump
* inc [bp + 4] is ambiguous (increment a byte or a word?), however from the dump it appears to be a word increment, which is correct
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by alexfru »

SpyderTL wrote:Also, you have to tell the compiler where this code will be located:

Code: Select all

org 7c00
It must've been omitted just like the string. The string address (the only non-PC-relative address in the code) is in the dump and is correct.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by Octocontrabass »

How are you running this code on your test PCs?

Which assembler are you using?
Kolodez
Posts: 9
Joined: Wed Jul 27, 2016 5:37 am

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by Kolodez »

Thanks for your quick responses. Unfortunately, the problem is still present.

@SpyderTL:
Try something like "jmp far start"
I added "EA 05 00 C0 07" before the code, which means "jmp far 0x07C0:0x0005". The behaviour changed, but still not as expected (and it still works fine on the PC where it has worked before).

@alexfru:
Sure, my PC is at least i386. I have a Intel Pentium CPU G2120. You are right that my "inc [bp + 4]" should be "inc WORD PTR [bp + 4]" instead. I forgot it. ;)

What do you mean by the following? Why could this be important with different code?
it starts with CS:IP=0x7C0:0 instead of CS:IP=0:0x7C00
@Octocontrabass:
I put the byte code on a USB stick and choose it in the boot menu. As I said, this worked fine with more simple code on this PC and the code I posted here originally also goes fine on other PCs with exactly the same "testing" method.

I don't use any assembler, I translate it into binary on my own (this should be fine for a "hello world" program). ;)
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by Octocontrabass »

Kolodez wrote:I put the byte code on a USB stick and choose it in the boot menu. As I said, this worked fine with more simple code on this PC and the code I posted here originally also goes fine on other PCs with exactly the same "testing" method.
The BIOS might think your code is a BPB, and try to "correct" it. This corrupts the code and causes it to crash. In order to prevent this from happening, you must have exactly one of the following:
  • An actual BPB, or
  • A partition table with exactly one active partition
Kolodez wrote:I don't use any assembler, I translate it into binary on my own (this should be fine for a "hello world" program). ;)
I think you'll be better off using an assembler instead of writing machine code by hand. :roll: (I like YASM, but there are several to choose from.)
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by Techel »

Check the stack location.
Nope, it's fine.
Last edited by Techel on Thu Jul 28, 2016 12:40 pm, edited 3 times in total.
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by SpyderTL »

Kolodez wrote:I added "EA 05 00 C0 07" before the code, which means "jmp far 0x07C0:0x0005". The behaviour changed, but still not as expected (and it still works fine on the PC where it has worked before).
I assume you adjusted your string address when you added these bytes...

Try clearing the direction flag at the start of your code. The BIOS may be leaving it set, which will make your string print code run backwards. :)

There's also an extremely unlikely chance that your BIOS may be starting up in 32-bit mode. You can try compiling with [bits 32] and see if it works...

Also, check your BIOS settings to see if there is anything obvious that may be causing problems at startup. (Like booting in 32-bit mode...)
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by onlyonemac »

Kolodez wrote:I don't use any assembler, I translate it into binary on my own (this should be fine for a "hello world" program). ;)
That is very error-prone, and time-consuming. I'm surprised that your code is actually error-free enough to work on the other PCs.

That's a compliment by the way. :-)
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
linuxyne
Member
Member
Posts: 211
Joined: Sat Jul 02, 2016 7:02 am

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by linuxyne »

Kolodez wrote:I've already tested the most simple bootstrap ever, namely just "int 0x10" with AX=0x0E21 and BX=0x0007. This worked on all PCs.
Can you sprinkle that simple statement within your code to see how many dots are printed before the code goes silent? For instance, before cli, after sti, after push, after call, etc.

I assume that the system #3 does not reboot upon running your code. You can insert instructions to make the system reboot, and move the set of instructions around your code to see how far the system does reboot under your command.

Note also that 'ret' might need changing to 'ret 2', if you plan to use stack after the return.
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by Techel »

Am I missing something, or is his stack location set to 0x0000:0?
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by SpyderTL »

Techel wrote:Am I missing something, or is his stack location set to 0x0000:0?
Nope, your not missing anything. That's perfectly legal, assuming you have more than 1 MB of RAM.

The first time you push anything to the stack, it will roll over to 0000:fffe, and store whatever value you pushed to that address.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by Techel »

Yeah, I thought about that, but I accentially assumed it would underflow to 0xFFFF:0xFFFE :o
Well then, follow linuxyne's advice.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: "Hello world" bootstrap works only on 2 of 3 PCs

Post by Octocontrabass »

Kolodez wrote:What do you mean by the following? Why could this be important with different code?
it starts with CS:IP=0x7C0:0 instead of CS:IP=0:0x7C00
Some instructions implicitly (or explicitly, with the CS: prefix) rely on the value of CS. Different PCs will boot with different values of CS. If you haven't used a far jump or some equivalent to set CS, your code will fail on some PCs. This issue doesn't affect the code you posted.
SpyderTL wrote:Try clearing the direction flag at the start of your code. The BIOS may be leaving it set, which will make your string print code run backwards. :)
The direction flag only affects string instructions, and there aren't any in this code.


If you follow linuxyne's advice, you'll discover that the corruption occurs where the disk geometry would go if you had a BPB. :wink:
Post Reply