OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Jul 20, 2019 8:20 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Does every PC-BIOS use the 'standard' 7C00 address?
PostPosted: Mon Jul 01, 2019 3:15 pm 
Offline
Member
Member
User avatar

Joined: Tue Dec 11, 2018 3:13 pm
Posts: 28
I just had this thought the other day... Every tutorial about this subject mentions "07C0:0000 / 0000:7C00" to be where the PC-BIOS load the first disk sector. With how not-standard the different PC-BIOS tend to be, to me it feels like it would be best not the trust the PC-BIOS to load into that specific address, and to load specific data yourself, from the disk, into an address-space known by you, so that you are absolutely, 100% aware of where things are being located in memory.

That said, I'm aware that most (and even pretty much all virtual machines) load into that address, but I was just curious, and was wondering if my logic is sound or not. I'm working on a very robust boot-loader, and was just wondering if it's worth it to just not worry about this aspect. Thanks!


Top
 Profile  
 
 Post subject: Re: Does every PC-BIOS use the 'standard' 7C00 address?
PostPosted: Mon Jul 01, 2019 3:29 pm 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7382
Location: Germany
saltlamp wrote:
Every tutorial about this subject mentions "07C0:0000 / 0000:7C00" to be where the PC-BIOS load the first disk sector. With how not-standard the different PC-BIOS tend to be, to me it feels like it would be best not the trust the PC-BIOS to load into that specific address, and to load specific data yourself, from the disk, into an address-space known by you...


The point is that this is the memory address that the BIOS loads that first sector to before the first byte of your code ever gets executed. Because, you know, your code is in that first disk sector, and as long as it's not loaded to memory, it can't be executed. ;-)

What traditional boot loaders do is relocate themselves, then chainload the active partition's bootsector. That relocation would not work if the BIOS had loaded that first sector to some other address. It wouldn't work for the vast majority of boot sectors out there, the BIOS in question would be broken.

So there's really no need to go paranoid about whether a BIOS might have loaded your code somewhere else. (Especially since legacy BIOS is going the way of the Dodo, like many other things like FAT-12 floppies...)

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: Does every PC-BIOS use the 'standard' 7C00 address?
PostPosted: Mon Jul 01, 2019 3:33 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 440
Any machine with legacy BIOS will load the boot sector to physical address 0x07c00 and then transfer control to it (usually a FAR JMP or equivalent). It is that simple. The memory address 0x07c0:0x0000 and 0000:0x7c00 are actually the physical location in memory. To compute physical address from real mode segment:offset pair you shift the segment left 4 bits (or multiply by 16 decimal) and then add the offset. So (0x07c0<<4)+0x0000=0x07c00 and (0x0000<<4)+0x7c00=0x07c00 too.

The difference is what address the BIOS uses to FAR JMP to your code. A FAR JMP to 0x0000:0x7c00 will set CS to 0x0000 and IP to 0x7c00 and a FAR JMP to 0x07c0:0x0000 will set CS to 0x07c0 and IP to 0x0000. What is important is that your bootloader loads the segment registers accordingly when it starts running.

More on 20-bit segment:offset addressing works can be found in this Starman's blog


Last edited by MichaelPetch on Mon Jul 01, 2019 3:37 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Does every PC-BIOS use the 'standard' 7C00 address?
PostPosted: Mon Jul 01, 2019 3:37 pm 
Offline
Member
Member
User avatar

Joined: Tue Dec 11, 2018 3:13 pm
Posts: 28
MichaelPetch wrote:
Any machine with legacy BIOS will transfer control to your bootloader at physical address 0x07c00. It is that simple. The memory address 0x07c0:0x0000 and 0000:0x7c00 are actually the same place in memory. To compute physical address from real mode segment:offset pair you shift the segment left 4 bits (or multiply by 16 decimal) and then add the offset. So (0x07c0<<4)+0x0000=0x07c00 and (0x0000<<4)+0x7c00=0x07c00 too.

The difference is what address the BIOS uses to FAR JMP to your code. A FAR JMP to 0x0000:0x7c00 will set CS to 0x0000 and IP to 0x7c00 and a FAR JMP to 0x07c0:0x0000 will set CS to 0x07c0 and IP to 0x0000. What is important is that your bootloader loads the segment registers accordingly when it starts running.

More on 20-bit segment:offset addressing works can be found in this Starman's blog


I am aware that they are the same addresses. I just used both because some tutorials say to use the segment of 07C0, versus others telling you to use the offest of 7C00


Top
 Profile  
 
 Post subject: Re: Does every PC-BIOS use the 'standard' 7C00 address?
PostPosted: Mon Jul 01, 2019 3:40 pm 
Offline
Member
Member
User avatar

Joined: Tue Dec 11, 2018 3:13 pm
Posts: 28
Solar wrote:
saltlamp wrote:
Every tutorial about this subject mentions "07C0:0000 / 0000:7C00" to be where the PC-BIOS load the first disk sector. With how not-standard the different PC-BIOS tend to be, to me it feels like it would be best not the trust the PC-BIOS to load into that specific address, and to load specific data yourself, from the disk, into an address-space known by you...


The point is that this is the memory address that the BIOS loads that first sector to before the first byte of your code ever gets executed. Because, you know, your code is in that first disk sector, and as long as it's not loaded to memory, it can't be executed. ;-)

What traditional boot loaders do is relocate themselves, then chainload the active partition's bootsector. That relocation would not work if the BIOS had loaded that first sector to some other address. It wouldn't work for the vast majority of boot sectors out there, the BIOS in question would be broken.

So there's really no need to go paranoid about whether a BIOS might have loaded your code somewhere else. (Especially since legacy BIOS is going the way of the Dodo, like many other things like FAT-12 floppies...)


Ah, okay. I see. I was just wondering, cuz some bootloaders don't set the lower half of the DX register correctly, some implicitly (so I've heard) do a CLI/STI wrap around a SS and SP register change, and some don't set the carry flag properly after an interrupt.

In all of this, it was making me worried about the portability of the boot-loader, lol, but if that address is not a problem, then I won't treat it as one! :)


Top
 Profile  
 
 Post subject: Re: Does every PC-BIOS use the 'standard' 7C00 address?
PostPosted: Mon Jul 01, 2019 4:10 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 440
You don't have to care which one the BIOS uses if you code your bootloader correctly. You can code your bootloader to not care whether it was reached with 0x07c0:0x0000 or 0x7c00:0x0000. You only need to code a bootloader to not care which. Which segment and offset you use is a simple choice as long as they initially map to physical address 0x07c00. You said you should read specific data yourself. You have no control over the BIOS loading your boot sector to 0x07c00 in memory. What is guaranteed is that your boot sector will ALWAYS be at physical address 0x07c00 through 0x07DFF. The bootsector and the data in the boot sector is never anywhere but those locations on anything that is appearing as an IBM-PC.

I actually discourage use of 0x07c0:0x0000 (contrary to some of the tutorials) for anyone who intends to jump into protected mode in their boot sector as the LGDT command requires a linear address and you need to fix up the memory locations.

This code sets everything up (including CS which isn't necessary for most bootloader, but I show it anyway) and is guaranteed to allow your bootloader to run any code and use data no matter whether it was arrived at through 0x07c0:0x0000 or 0x0000:0x7c00:
Code:
bits 16
org 0x7c00

start:
    ; Place BIOS Parameter Block here if needed
    ; ...

main:
    jmp 0x0000:.setcs          ; Set CS to 0x0000 and IP to 0x7c00
.setcs:
                               ; This FAR JMP isn't actually needed if you
                               ; know your code doesn't need the value of CS
                               ; to be a particular segment. See this SO question/answer
                               ; for an example where this FAR JMP would be needed:
                               ; https://stackoverflow.com/questions/34548325/near-call-jump-tables-dont-always-work-in-a-bootloader

    xor ax, ax                 ; Set DS=ES=0
    mov ds, ax
    mov es, ax

;    cli                       ; You only need CLI/STI around SS:SP update
                               ; To avoid a bug in some batches of ancient 8088 CPUs
                               ; see: https://books.google.ca/books?id=1L7PVOhfUIoC&lpg=PA492&pg=PA492#v=onepage&q&f=false

    mov ss, ax                 ; Place stack anywhere out of the way
    mov sp, 0x7c00             ; This example sets it to grow down from below the bootloader
                               ; You should always set the stack yourself espeically
                               ; if you read data/code into memory as you don't
                               ; want to clobber the stack the BIOS set as a default.
;    sti

    cld                        ; Set the direction flag (DF) forward. Needed if your
                               ; bootloader uses any string instructions like
                               ; movs?, scas?, stos? etc.

    ; Put rest of bootloader here


Top
 Profile  
 
 Post subject: Re: Does every PC-BIOS use the 'standard' 7C00 address?
PostPosted: Tue Jul 02, 2019 3:40 pm 
Offline
Member
Member
User avatar

Joined: Thu Oct 13, 2016 4:55 pm
Posts: 326
Hi,

saltlamp wrote:
some bootloaders don't set the lower half of the DX register correctly
That's because the lower half of the DX register is the DL register, which is set by the BIOS and contains the drive code from where your code was loaded. It's 00h if your code was loaded from a floppy, 80h if loaded from the first (master) hard disk, 81h for the second (slave) disk, and in some cases could be E0h if the sector loaded from CD-ROM. If a bootloader sets DL, then it will most certainly loose this information.

saltlamp wrote:
some implicitly (so I've heard) do a CLI/STI wrap around a SS and SP register change, and some don't set the carry flag properly after an interrupt.
It is always a good idea to start a bootloader with CLI+CLC to clear interrupts and set up direction flag until you finish with setting up the segment registers and the stack.

saltlamp wrote:
In all of this, it was making me worried about the portability of the boot-loader, lol, but if that address is not a problem, then I won't treat it as one! :)
But it is a problem. Consider this: you assume CS=0 and you make a jump to 7C80 for example. If BIOS has loaded the CS:IP registers with 7C0:0, then you'll jump to 7C0:7C80, which is a different physical address than 0:7C80 (or 7C0:80).

Take @Solar's and @MichaelPetch's advice and first thing set up your segment registers correctly. Not only CS, but DS, ES and SS too.
Code:
boot_sector_prologue:
cli
clc
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 7C00h
jmp far 0:start
start:
sti
mov byte [bootdrive], dl


Cheers,
bzt


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: AssemblyDavid, Google [Bot] and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group