Bootblock: 0x55AA or 0xAA55?

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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Bootblock: 0x55AA or 0xAA55?

Post by Solar »

Dudes, I'm not sure what white powder they crumbled into the air conditioner today, but...

...CrazyBuddha's BabyStep tutorial says it must be "dw 0xAA55", GoogleBattle says it's 0xAA55...

...but when I tried to follow the tutorial (old GRUB affectionado though I am, I wanted to write a bootsector once in my life), Bochs stubbornly refused to accept either

Code: Select all

times 510-($-$$) db 0
dw 0xAA55
in the NASM source, or

Code: Select all

.org 510
.word 0xAA55
in the GAS source. ("Not a bootable disk".)

Reversing that to 0x55AA worked.

Is this just me, a strange rift in the time/space continuum, a bug in Bochs (2.1.1), or is it really that no-one ever actually tested this and we have to edit all examples in the FAQ?

This is a x86 using a i586-elf cross-binutils and the following (GAS) source (the NASM source in the tutorial generates identical binary):

Code: Select all

.code16
.text

   movw $0x07c0, %ax
   movw %ax, %ds
   movw $msg, %si

ch_loop:
   lodsb
   or %al, %al
   jz hang
   mov $0x0e, %ah
   int $0x10
   jmp ch_loop

hang:
   jmp hang

msg:
.asciz "Welcome to BabySteps."

.org 510
.word 0x55AA
as -o <file>.o <file>.s
ld -Ttext 0x0 -o bootsector bootsector.o --oformat binary --entry=0

If it's really that everyone just copied each other and never actually put this to the test, I'll fall over backwards from laughing... :-D
Every good solution is obvious once you've found it.
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Bootblock: 0x55AA or 0xAA55?

Post by distantvoices »

in very old sources of mine (ere I've switched over to GRUB) I've found 0xaa55. They've worked, so I dunno. *shrugs*

We should put it to the relevant faq, stating that if it isn't recognized as valid boot disk with 0xaa55 the author should change over to 0x55aa.

HOnestly, I have no clue, why it behaves like that.

Sorry if I couldna bring elucidation to that dark tunnel of yours *gg*
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
AR

Re:Bootblock: 0x55AA or 0xAA55?

Post by AR »

0xAA55 is the correct signature (or 0x55 0xAA in hex disassembly), if it works the other way round then it must be something wrong with Bochs or the assembler is operating in big-endian (how exactly NASM would manage this, I have no idea).

Did you try hex disassembling the output and comparing the results?
distantvoices
Member
Member
Posts: 1600
Joined: Wed Oct 18, 2006 11:59 am
Location: Vienna/Austria
Contact:

Re:Bootblock: 0x55AA or 0xAA55?

Post by distantvoices »

you mean lsw order?
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Bootblock: 0x55AA or 0xAA55?

Post by Solar »

AR wrote: 0xAA55 is the correct signature (or 0x55 0xAA in hex disassembly)...
HAH!

If you want 0000 0000 55aa in the hexdump, .word 0x55AA is correct! Think little endian... all the code examples are wrong!

ROTFL!
Every good solution is obvious once you've found it.
Kemp

Re:Bootblock: 0x55AA or 0xAA55?

Post by Kemp »

I use 0AA550000h, which works under Virtual PC, haven't tried it on a real system yet, probably try it tonight to confirm.

Assembler = TASM

Thought if you used 0xAA55 in the code it'd end up as 55AA in the actual binary?
AR

Re:Bootblock: 0x55AA or 0xAA55?

Post by AR »

Code: Select all

times 510-($-$$) nop   ; Fill the rest of the sector with Null operations
dw 0xAA55      ; Boot signature
This generates a valid signature, Intel x86 byte ordering says lowest byte first, .word 0x55AA outputs 0xAA 0x55, 0xAA55 outputs 0x55 0xAA.

This can be demonstrated with the following simple example:

Code: Select all

movw $0x2021, 0xB8000
Sets character to 0x21, sets attribute 0x20 (Exclamation mark in black on green)
oswizard

Re:Bootblock: 0x55AA or 0xAA55?

Post by oswizard »

Solar wrote:
AR wrote: 0xAA55 is the correct signature (or 0x55 0xAA in hex disassembly)...
HAH!

If you want 0000 0000 55aa in the hexdump, .word 0x55AA is correct! Think little endian... all the code examples are wrong!

ROTFL!
Are you sure? Assuming AR is correct (and my source code is correct), the correct signature appears in the hexdump as 0x55 0xAA, which would be dw 0xAA55 - the first byte (in the hexdump) is the least significant byte - the word would be reversed.

To avoid this confusion, why not db 0x55, 0xAA? :)

Mike
GLneo

Re:Bootblock: 0x55AA or 0xAA55?

Post by GLneo »

whats the point of righting it one way just to have the asmbler reverse it, we could just write it backwards to begin?
AR

Re:Bootblock: 0x55AA or 0xAA55?

Post by AR »

It isn't backwards per se, it is just stored backwards in memory.

Architectures like PowerPC are 'as is' (ie. 0xAA55 comes out as 0xAA 0x55 in memory, highest byte first).
oswizard

Re:Bootblock: 0x55AA or 0xAA55?

Post by oswizard »

[edit]AR, you beat me to it! :)[/edit]

All intel (and therefore AMD) processors are little-endian, meaning when a multi-byte value is written to memory, it is stored with the least significant byte first. For example, the 4-byte value 0xEFBEADDE would be seen in memory as DE AD BE EF.

Why? Although it may be very confusing working with it manually, to work on a big-endian machine like the PowerPC would seem strange to me. Take, for instance, the instruction add eax, dword [ebx]. The processor needs to perform addition from the least-significant bit to the most-significant bit, right? So in little-endian mode, it can read the first byte, add it and update the carry, read the second byte, add it and update carry, etc. (although in a real processor I'm sure it is done in a 32-bit operation)

Another example is seen with casts in C. If you write:

Code: Select all

unsigned long *y = &param1;
unsigned short x = (unsigned short)*y;
to perform the cast the processor can just read the first two bytes of y in memory and store them in x, instead of having to know the size of the object pointed to by y. It doesn't care. On a big endian machine, the size would have to be known.

Yes, it does seem strange at first, but I think it works out better for other things.

Mike
GLneo

Re:Bootblock: 0x55AA or 0xAA55?

Post by GLneo »

so in all actuality, the bios likes 0x55AA, you just have to write it weird, is that about it???
AR

Re:Bootblock: 0x55AA or 0xAA55?

Post by AR »

No it likes 0x55, 0xAA. You can save the trouble by just using bytes for it (db 0x55, 0xAA). Writing it "weird" is a matter of perception, as Mike explained it can be more efficient like this, it just confuses the programmer.
smiddy

Re:Bootblock: 0x55AA or 0xAA55?

Post by smiddy »

Here is the end of my floppy boot sector coded with FASM (should work with NASM):

Code: Select all

TIMES 510-($-BootSector)    DB 0
                            DW 0AA55h
Now, as many have said, placing each byte would be:

Code: Select all

TIMES 510-($-BootSector)    DB 0
                            DB 055h
                            DB 0AAh
The Endian-ness of Intel...
kerim

Re:Bootblock: 0x55AA or 0xAA55?

Post by kerim »

when I wrote a small bootloader for my OS, the boot signature I used was 0xAA55 and I tested the bootloader physicaly, by restarting the computer with floppy inside the drive, and it booted the kernel. So it must be 0xAA55. Or it doesn't ?
Post Reply