Page 1 of 2
Safe init for bootloader
Posted: Mon Dec 21, 2015 11:54 am
by 0b00000000
Code: Select all
bits 16
org 0x7c00
jmp 0x0000:start
start:
call init
clt
hlt
init:
mov ax, 0
mov ss, ax
mov sp, 0x7c00
mov ds, ax
mov es, ax
mov cs, ax
Hi,
the above is first attempt at a safe init: to be called before doing anything in a bootloader. It's a bit of a mismatch of various pointers I've been able to find here on the wiki and elsewhere on the web. So, it probably contains errors and/or could be improved on.
It seems reasonably well known that it is good practice to set SS and SP as we have no guarantee what state the BIOS left them in. I guess it could be debated what the best value to set them to is. How large a stack do we need? Which area of memory to place the stack in?
I found elsewhere that it is a good idea to zero ES, DS and CS. For CS it seems obvious why as this has implications for segmented memory references. Anybody care to comment on the ES and DS?
I guess what I really have on my mind is whether it would be a good idea to initialise any other registers. I guess it would be good to have a well defined starting point for all registers.
0x00
Re: Safe init for bootloader
Posted: Mon Dec 21, 2015 12:38 pm
by midkid
DS is used when referencing locations in the code (such as functions and such, usually by the assembler), so that has to be set such that the right location is found. If org is 0, set DS to 0x7c0, as (0x7c0 * 16) + 0 == 0x7c00 == location of the code. If org is 0x7c00, set DS to 0, as (0 * 16) + 0x7c00 == 0x7c00.
As for ES, it's an extra segment register. You may set it wherever you want. It's used by the stos* operations, so it should be set right for those.
About the others, CS should be set right by the BIOS, pointing to the code (I may be wrong), and FS and GS are extra too.
Generally, it doesn't matter what state the registers are in, unless you use them. The most used are DS and SS, so as long as those are set right, you should be fine.
Please correct me if I'm wrong, though. I'm also new to this.
Re: Safe init for bootloader
Posted: Mon Dec 21, 2015 12:50 pm
by intx13
Your OS/bootloader design can drive the selection of starting segment register values - there's no right or "safe" values. For example, if you are planning on relocating your code to higher addresses, it won't be very useful to have the segment registers zeroed. If you're going to switch to protected mode or long mode, it doesn't matter at all what you set them to now (unless you need stack before you do that).
CS is typically set by bootloaders because some BIOSs jump to the boot code with CS=07C0, IP=0000, while (most) others jump there with CS=0, IP=7C00. By performing a long jump the bootloader ensures that CS is in a known state.
Re: Safe init for bootloader
Posted: Mon Dec 21, 2015 2:37 pm
by CelestialMechanic
I'm amazed no one has seen the glaring errors in this code excerpt:
Code: Select all
bits 16
org 0x7c00
jmp 0x0000:start
start:
call init
clt
hlt
init:
mov ax, 0
mov ss, ax
mov sp, 0x7c00
mov ds, ax
mov es, ax
mov cs, ax
First, you call the routine "init". Where is the stack pointing to? Answer: wherever the BIOS left it. Do you know where it is? Probably not. If you knew where it was on your machine/emulator, how do you know it isn't somewhere else on another system?
Second, your "init" code sets a new stack pointer. How is it ever going to return to the place it was called from? If you ever do return from "init" it will probably be to some unknown location.
Suggestion: perform the actions in your "init" routine first before calling any subroutines. Once you have set up the stack then you can call subroutines to your heart's content.
Another suggestion which I have used and recommended elsewhere is set your stack pointer a little lower, say 0x7bc0, which allows 64 byte above the stack and below the boot sector for data. Then set the BP register to 0x7c00 with MOV BP,7C00H. Keep SS=0 and BP=0x7c00 throughout the real-mode portion of the boot and you can use MOV reg,[BP+offset] addressing with positive offsets to access the BPB (BIOS Parameter Block) if you decide to have one in the boot sector, and use negative offsets to access your data. If the data and the BPB are within 127 bytes of the beginning of the boot sector the resulting instruction will be three bytes long instead of four. Remember, every byte counts!
Re: Safe init for bootloader
Posted: Mon Dec 21, 2015 2:56 pm
by iansjack
That code won't even assemble.
Re: Safe init for bootloader
Posted: Mon Dec 21, 2015 11:57 pm
by Antti
In general it is good to set the CS segment register to a known value. At the same time it is also very essential to understand that it actually does not have that much effect on normal real-mode code. All short jumps, near jumps and near calls use relative addressing, so the actual CS:IP values are not so important assuming that there are no overflows. However, as a good programming practice I recommend setting the CS anyway. If writing code with a small margin of safety, it will backfire sooner or later.
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 2:15 am
by 0b00000000
So, now I'm wondering how on earth would it be possible to both:
a) set the requirement of some systems for the first instruction to be a short JMP
b) make sure any or all of SS, SP, CS, DS, ES are properly set before making that short JMP
0x00
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 2:19 am
by Techel
You dont need any of these set up when performing a relative jump.
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 4:21 am
by 0b00000000
If we refuse to support the first instruction must be a short jump requirement is that a lot of systems that would be excluded?
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 4:30 am
by Combuster
Roflo wrote:You dont need any of these set up when performing a relative jump.
0b00000000 wrote:If we refuse to support the first instruction must be a short jump requirement is that a lot of systems that would be excluded?
Why would you even bother with the risk of losing platforms when it's trivial not to do so?
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 5:04 am
by 0b00000000
Combuster wrote:Roflo wrote:You dont need any of these set up when performing a relative jump.
0b00000000 wrote:If we refuse to support the first instruction must be a short jump requirement is that a lot of systems that would be excluded?
Why would you even bother with the risk of losing platforms when it's trivial not to do so?
I guess there are a multitude of reasons you might like to do that:
e.g. Perhaps you would like to track the types of hardware your code is running on so you know where to best concentrate your development efforts. If you have a different download for each system setup you don't need to beg your users for their dmesg. The download stats will tell you immediately what hardware distribution your user base is running on.
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 5:08 am
by iansjack
What have download stats got to do with boot code? I think you can presume that before someone downloads code their system has already booted.
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 5:27 am
by Combuster
I don't think users will fill out a (virtual) form saying "my BIOS has this and this quirk" before grabbing the download in question.
How did you even get to that bogus argument in the first place?
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 5:49 am
by 0b00000000
Combuster wrote:I don't think users will fill out a (virtual) form saying "my BIOS has this and this quirk" before grabbing the download in question.
How did you even get to that bogus argument in the first place?
I guess you would have an image for every know hardware setup that has been sold / is being sold in any significant quantities. For those that built there own setup from parts I guess you could have images for each combination of processor/floppy drive (if boot media is a floppy) and so on. If you had an image for each complete hardware setup and did you best to make sure your image will only work if they are honest about what hardware they are running on then your download stats would be a good indication of what hardware your user base is running on.
Re: Safe init for bootloader
Posted: Tue Dec 22, 2015 6:22 am
by iansjack
I'm beginning to suspect a Troll here. The posts are getting wilder and wilder.