Page 1 of 2

state at 0x7c00 (x86)

Posted: Tue Feb 22, 2011 7:30 pm
by a5498828
When i get control in my bootsector, what is the state of segment registers and sp?

I know only that dl will contain index to my drive wich i booted from.
IP will be propably at 0x7c00, but it might be 0 as well, with cs - 0x07c0.

- whats in segment registers
- how much stack do i have
- is it the same at 8086 and i7, can i assume its always the same


I every time initialize segment registers to 0, just to be sure, but i dont know if i really must do that, if its a standard to pass zeroed segmrnts at 7c00.

Re: state at 0x7c00

Posted: Tue Feb 22, 2011 7:37 pm
by VolTeK
a5498828 wrote:- is it the same at 8086 and i7, can i assume its always the same
As far as i know, different processors = different instructions PLUS the regular standard x86 instructions (if x86). At boot you cant change your code depending upon the processor if the type of processor doesnt support booting at a certain point, then many would have to create different os's for different processors. That part AFAIK is universal

Re: state at 0x7c00 (x86)

Posted: Tue Feb 22, 2011 8:54 pm
by Coty
This is BIOS dependent.

CS - should be 0
IP - should be 0x7C00
ES - Should be 0 because your boot sector was loaded to 0x0000:0x7C00
DS - This also should be 0?
SS:SP - Depends were the BIOS places the stack...

If you want to find out your specific segments you could echo them to the screen... But I think it would be best not to assume what they are and set them your self.

Re: state at 0x7c00 (x86)

Posted: Tue Feb 22, 2011 9:25 pm
by gerryg400
a5498828 wrote:When i get control in my bootsector, what is the state of segment registers and sp?

I know only that dl will contain index to my drive wich i booted from.
IP will be propably at 0x7c00, but it might be 0 as well, with cs - 0x07c0.

- whats in segment registers
- how much stack do i have
- is it the same at 8086 and i7, can i assume its always the same


I every time initialize segment registers to 0, just to be sure, but i dont know if i really must do that, if its a standard to pass zeroed segmrnts at 7c00.
There are many PCs with BIOSes that load at 0x07C0:0x0000. It's wise to assume nothing.

Re: state at 0x7c00 (x86)

Posted: Wed Feb 23, 2011 12:12 am
by Combuster
There are only two things you can rely on:
CS:IP points to 0x7c00 linear (see above)
DL contains the bios drive booted from.

Re: state at 0x7c00 (x86)

Posted: Wed Feb 23, 2011 5:54 am
by rdos
Combuster wrote:There are only two things you can rely on:
CS:IP points to 0x7c00 linear (see above)
DL contains the bios drive booted from.
Is it 100% certain that DL will always contain the boot drive? The actual boot-sector will also contain the drive, but has the disadvantage of being wrong if it is a CF disk, and it is inserted into a computer that has the CF at another drive ID.

Re: state at 0x7c00 (x86)

Posted: Wed Feb 23, 2011 6:13 am
by Brendan
Hi,
rdos wrote:Is it 100% certain that DL will always contain the boot drive?
Yes (unless it's been chainloaded by something completely broken).
rdos wrote:The actual boot-sector will also contain the drive, but has the disadvantage of being wrong if it is a CF disk, and it is inserted into a computer that has the CF at another drive ID.
The boot sector (normally) contains nothing to identify which drive ID it came from; even if it's a floppy with a "BIOS Parameter Block" and even if there's a partition table.

It is possible for an OS to store a drive ID in it's own boot loader, but only a stupid/broken OS would do that because it'd fail in common situations. For example, create a bootable floppy (in the first floppy drive), then put that floppy into the second floppy drive and use something (anything) like GRUB to chainload it. You can do the same with hard drives (e.g. install the OS on the first hard drive, then install a new "first" hard drive and setup the old "first" hard drive as the second drive, then chainload it).


Cheers,

Brendan

Re: state at 0x7c00 (x86)

Posted: Wed Feb 23, 2011 6:59 am
by Solar
Brendan wrote:It is possible for an OS to store a drive ID in it's own boot loader, but only a stupid/broken OS would do that because it'd fail in common situations [...] (e.g. install the OS on the first hard drive, then install a new "first" hard drive and setup the old "first" hard drive as the second drive, then chainload it).
To wit, several versions of Microsoft Windows.

Re: state at 0x7c00 (x86)

Posted: Wed Feb 23, 2011 11:01 am
by rdos
Brendan wrote:The boot sector (normally) contains nothing to identify which drive ID it came from; even if it's a floppy with a "BIOS Parameter Block" and even if there's a partition table.
I put the boot-sector in the MBR, so I do not use chainloading. When I install with another OS, I use GRUB instead as this is more convinient. The BIOS parameter block does contain a drive-ID (maybe not documented, but at least some DOS-versions used it).

Anyhow, it seems like I should redo my boot-sector and use DL instead of relying on disk contents.

Re: state at 0x7c00 (x86)

Posted: Wed Feb 23, 2011 11:26 am
by Brendan
Hi,
rdos wrote:
Brendan wrote:The boot sector (normally) contains nothing to identify which drive ID it came from; even if it's a floppy with a "BIOS Parameter Block" and even if there's a partition table.
I put the boot-sector in the MBR, so I do not use chainloading.
For a general purpose OS there's no way to prevent the end user from chainloading; and for a general purpose OS, "good" code is code that works in all possible situations.

For an embedded system, you don't need it to work in all possible situations - you only really care about some specific/controlled situations, and therefore don't really need (what someone writing a general purpose OS would consider) "good" code.
rdos wrote:The BIOS parameter block does contain a drive-ID (maybe not documented, but at least some DOS-versions used it).
Yeah - only for "BPB version 4.0 and later". The BPB might still be important for OS developers that work for Microsoft. For everyone else you only really need the BPB so that Windows is able to format the floppy afterwards (so Windows doesn't complain about "unsupported or corrupt media" and sit in the corner crying like a scared baby, instead doing what it's told like a useful OS). :D


Cheers,

Brendan

Re: state at 0x7c00 (x86)

Posted: Wed Feb 23, 2011 12:09 pm
by rdos
Brendan wrote:For a general purpose OS there's no way to prevent the end user from chainloading; and for a general purpose OS, "good" code is code that works in all possible situations.

For an embedded system, you don't need it to work in all possible situations - you only really care about some specific/controlled situations, and therefore don't really need (what someone writing a general purpose OS would consider) "good" code.
My command shell contains some pretty powerful (and dangerous) commands. One will wipe an entire disk and install RDOS boot-sector and second stage loader in the MBR, and the following 13 sectors. Another will create partitions (and format them). To allow for speedy disc-creation I also have a program that will automatically create partions and download files from an FTP-server.
Brendan wrote:Yeah - only for "BPB version 4.0 and later". The BPB might still be important for OS developers that work for Microsoft. For everyone else you only really need the BPB so that Windows is able to format the floppy afterwards (so Windows doesn't complain about "unsupported or corrupt media" and sit in the corner crying like a scared baby, instead doing what it's told like a useful OS). :D
:D

I fixed the issue. The only thing that was needed was to save DL into the BPB-field at the start of the boot sector code. Then everything works as expected. I'll need to test it on a few other machines, but it seems like it should work. I have another embedded board with different settings for CF disk that would be interesting to check.

BTW, Windows will not complain about the boot-sector, but it usually complains when I format a FAT32 disc, but as long as I can read Windows own formatted discs I see no reason to research that too much.

About the 7c00 issue, my boot sector starts with a far jump into segment 7c0 just to be sure that my offsets are correct regardless how BIOS passes control.

Re: state at 0x7c00 (x86)

Posted: Thu Feb 24, 2011 4:41 am
by egos

Re: state at 0x7c00 (x86)

Posted: Thu Feb 24, 2011 6:22 pm
by a5498828
so, cs:ip = always linear address, wich is rather obvoius
any other segment registers are unknown. What about stack? Can i allocate kilobytes of memory on it, or there is a popular limit?
can i rely on DL?
Lets say, that under 7c00 is a VBR (loaded by mbr). vbrs job is to load more of boot code and initialize os.
can i rely thet dl is a drive number? My vbr needs to load an os. It must pass drive number to int 13h functions. Can it rely on dl being preserved?
Is there any other way of checking what drive was booted?

Re: state at 0x7c00 (x86)

Posted: Thu Feb 24, 2011 6:35 pm
by Tosi
The stack most likely is whatever was used by the BIOS. I would recommend setting up a new one as soon as possible. It can be anywhere as long as you don't overwrite anything important like the IVT or the BIOS data area.

DL is the drive number, and will always be so unless something has caught on fire.

I'm pretty sure that the MBR should set the drive number for you, but I have never written an MBR or VBR so don't count me on that one.

As for other ways of checking the boot drive, there might be something like that in CMOS.

Most of this information was pretty easy to find using the wiki and google, and I've never written a full bootloader in my life. I would recommend brushing up on your searching skills.

Re: state at 0x7c00 (x86)

Posted: Fri Feb 25, 2011 2:27 am
by egos
a5498828 wrote:so, cs:ip = always linear address, wich is rather obvoius
Who said this? And what you mean when you say "linear address" about cs:ip?
a5498828 wrote:Lets say, that under 7c00 is a VBR (loaded by mbr). vbrs job is to load more of boot code and initialize os.
VBR is loaded at 7C00h. If you want to load some additional sectors under 7C00h you should set stack pointer to the buffer base or below it in VBR code. There is a one important point. If you use data from descriptor of boot partition you should store useful data in registers or VBR body (in memory) before initializing the stack.