Page 1 of 1
Question about boot sector
Posted: Sat Jun 24, 2006 10:50 am
by SmartBoy
Hello ..
i tryed to write my own boot sector and this is the code (with NASM)
Code: Select all
[ORG 0]
jmp 07C0h:start
msg db 'Hello World'
start:
mov ax, cs
mov ds, ax
mov es, ax
mov si, msg
print:
loadsb
cmp al,0
je hang
mov ah,0Eh
mov bx,7
int 10h
hang:
jmp hang
times 510-($-$$) db 0
dw 0AA55h
and i use this command "dd if=boot of=/dev/fd0" to write it's in the first sector of floppy .
but when i try to boot from floppy it's show error for me :-\
what is the error , and can i get programme like debug in DOS for Linux ?
finally sorry for my bad English .
Re:Question about boot sector
Posted: Sat Jun 24, 2006 11:07 am
by Kemp
what is the error
That is what you're meant to tell us so we can help you
Re:Question about boot sector
Posted: Sat Jun 24, 2006 11:11 am
by viral
Hello...
what is the error , and can i get programme like debug in DOS for Linux ?
I guess your boot loader is not getting booted or you are not able to see the Hello World msg...
Instead of testing your code on real pc, you can run your code in an emulator. There are many emulators available like
Qemu for Windows,
Bochs and
VMWare..
Re:Question about boot sector
Posted: Sat Jun 24, 2006 11:17 am
by blip
It doesn't work because you use loadsb which is not a valid instruction and NASM interprets it as a label. Use lodsb and turn on the orphan labels warning option from now on.
Re:Question about boot sector
Posted: Sat Jun 24, 2006 11:26 am
by Ryu
Ah, nice spot blip. Hmm I am suspicious at the fact there was an error output.
Re:Question about boot sector
Posted: Sat Jun 24, 2006 11:53 am
by Pype.Clicker
SmartBoy wrote:
but when i try to boot from floppy it's show error for me :-\
You should be more specific about wat's going wrong. Does it just hang? does it reboot? does it display the wrong thing?
You realise that you have a loop displaying a message until a nul character is met and have no nul character in your message? afaik, unlike C, asm strings exactly hold what you said and they do not automagically end with a nul char unless you add
Re:Question about boot sector
Posted: Sat Jun 24, 2006 12:21 pm
by chasetec
The error might be something about a non-system disk. Some systems require the first 3 bytes to be a short jump followed by a nop, some will run anything in the boot sector, some will require the signature (0xAA55) at the end, other with require the short jump, nop and 0xAA55.
In addition to the other changes mentioned here you might need to modify the start to:
Re:Question about boot sector
Posted: Sat Jun 24, 2006 2:49 pm
by ed_tait
i might be wrong but at the start of the code you use the directive.
[org 0]
the [org xxxx] directive tells the assembler what offset the program is to be loaded at and make sure that the lables are adjusted accordingly.
the problem is that bios loads the boot sector at offset 0x7c00 not at offset 0
this will mean that all your jumps will not go to the correct place in your program. this could explian why it doesn't work.
try replaceing [org 0] with:
as well os following the other advice on short jump, nop, and zero termination of strings.
Re:Question about boot sector
Posted: Sat Jun 24, 2006 3:17 pm
by Ryu
Well as I take it, the jmp short followed by a nop is typically found in FAT12 which follows the BPB. I really don't think the system BIOS will parse the BPB in anyway, nor should it take the address of a short jmp and jump directly there. The standard is that it should jmp to linear address 7C00h but no standard that I know of that specifies that CS should be at a particular segment apon entering bootsector. The BIOS should also by standard identify the sector to be a valid bootable bootsector by checking AA55h as the last word, otherwise it should not attempt to boot off it.
I see nothng wrong with ORG 0 and doing a jmp far 7C0:start, which I find it safer then using ORG 7C00 and assuming that the BIOS has left you with CS=0. Although you must specify the code is 16bits, otherwise if the assembler thinks its 32bits it will assemble a 32bit offset of "start" offset.
Re:Question about boot sector
Posted: Sat Jun 24, 2006 4:20 pm
by chasetec
Ryu wrote:
Well as I take it, the jmp short followed by a nop is typically found in FAT12 which follows the BPB. I really don't think the system BIOS will parse the BPB in anyway, nor should it take the address of a short jmp and jump directly there. The standard is that it should jmp to linear address 7C00h but no standard that I know of that specifies that CS should be at a particular segment apon entering bootsector. The BIOS should also by standard identify the sector to be a valid bootable bootsector by checking AA55h as the last word, otherwise it should not attempt to boot off it.
I see nothng wrong with ORG 0 and doing a jmp far 7C0:start, which I find it safer then using ORG 7C00 and assuming that the BIOS has left you with CS=0. Although you must specify the code is 16bits, otherwise if the assembler thinks its 32bits it will assemble a 32bit offset of "start" offset.
Some BIOSes really don't do the standard thing, IBM systems in particular. I've had systems that worked in all the ways I described. The short jmp followed by the nop *precedes* the BPB(not sure if you meant layout or position when you said "follows"). Most systems will work without the jump being short and most systems require the boot signature at the end but not all.
Additionally If you want your boot floppy to survive being inserted into a windows box you have to avoid using some areas in the BPB area. Some versions of Windows will write to them even if you have a non-fat12 disk and you aren't even doing a format(joy!).
You are right about the code segment. Lots of people make the mistake of doing something like this:
Code: Select all
Start:
mov ax,cs
mov ds,ax
mov es,ax
Here's a Fat12 NASM boot sector if the original poster wants an example
http://www.osdev.org/f12boot.asm. It show a valid Fat12 boot sector and BPB, it loads a file into memory after searching for in the root directory and jumps to it and has some text display code too. Just format a dos floppy and dd the compiled sector in place.
Re:Question about boot sector
Posted: Sat Jun 24, 2006 6:23 pm
by Ryu
Chase@OSDev wrote:
The short jmp followed by the nop *precedes* the BPB(not sure if you meant layout or position when you said "follows").
Sorry, I'm actually a bad speller and in grammer. I ment that you usually see a jmp short followed by a nop, which BPB is followed after those two instructions. Pretty sure everyone knows that the BPB has to start
after the third byte. Also means the
nop is just padding so that BPB is where is suppose to be.
Chase@OSDev wrote:
Most systems will work without the jump being short and most systems require the boot signature at the end but not all.
Personally I have troubles sinking this in my brain. The 3 bytes in FAT12 boot sector was dedicated so you can jump to entry point. This may be the jmp short + nop or a jmp near (which I don't recommend). If you don't wish to follow FAT12 then can very well be a jmp far which will take up 5 bytes or even no jump at all. I am clueless what IBM does, but I just don't see how not being a jmp short would make it unsupported by any x86 compatible system. And for the boot signature, if it is not required by some systems, I'm just seeing a very poor implementation on the BIOS side to be a compatible system. I'm pretty sure everyone once has left a non-bootable floppy disk in the drive one time or another, this would mean that system would try to boot from the unknown boot sector anyway, and can be very unpleasant effects.
Chase@OSDev wrote:
You are right about the code segment. Lots of people make the mistake of doing something like this:
Code: Select all
Start:
mov ax,cs
mov ds,ax
mov es,ax
After I took a look at the boot sector you given us, I think theres some misunderstandings (must be my grammer
). Your code does not do DS=ES=CS which is what StormBoy have but insted does DS=ES=7C0h and left CS alone. What I've tried to say was, if you do jmp far 7C0:start prior, DS=ES=CS is safe. And the other hand, something like DS=ES=7C0h and leaving CS alone, would be unsafe. Basically because you have assumed CS would be something.
To explain a bit, this goes back to differnt jmps and calls. For jumps specifically, the jump near operand is relative with CS segment, ex. jmp near 0004h which the processor will jmp to addess CS:0004h. Now, because no one ever stated any standard to set at a particular segment, CS is ambigous on differnt systems. Which means if the BIOS runs the boot sector with CS=0, your boot sector will run into problems, while a jmp far before hand to set CS would assure that its on the right track. Hope this makes any sense.
edit: some fixups.
edit: woah, it was es=ds=7C0h first then I fixed it up to es=ds=7C00h and now I changed it back, I was right just ot a bit confused. I found that thread which I also tried to explain this:
http://www.mega-tokyo.com/forum/index.p ... eadid=9533
Re:Question about boot sector
Posted: Sat Jun 24, 2006 8:41 pm
by chasetec
Ryu wrote:
Sorry, I'm actually a bad speller and in grammer.
Notice the edits on my posts
Ryu wrote: Also means the nop is just padding so that BPB is where is suppose to be.
Nope, on the few systems that don't pay attention to the boot signature you'll find that they see the short jmp followed by a nop as a kind of signature. Yes, it's stupid. Before my GF moved in with me I was collecting computers and I had 1 (forget the BIOS type) that worked like this.
Ryu wrote:If you don't wish to follow FAT12 then can very well be a jmp far which will take up 5 bytes or even no jump at all.
But you want a BPB, even if it's an empty one and you don't have a FAT FS, so that Windows won't write on top of you boot code if the disk is ever stuck in a MS system.
Ryu wrote:
And the other hand, something like DS=ES=7C00h and leaving CS alone, would be unsafe. Basically because you have assumed CS would be something.
To explain a bit, this goes back to differnt jmps and calls. For jumps specifically, the jump near operand is relative with CS segment, ex. jmp near 0004h which the processor will jmp to addess CS:0004h. Now, because no one ever stated any standard to set at a particular segment, CS is ambigous on differnt systems. Which means if the BIOS runs the boot sector with CS=0, your boot sector will run into problems, while a jmp far before hand to set CS would assure that its on the right track. Hope this makes any sense.
I'm not assuming CS is anything. If you use all short jumps everything is relative to CS:IP and since my ORG is 0 I'm just doing things like adding 4 to IP. It's possibly to completely bypass the whole issue of what the BIOS set CS to.
Re:Question about boot sector
Posted: Sun Jun 25, 2006 3:01 am
by blip
Ryu wrote:To explain a bit, this goes back to differnt jmps and calls. For jumps specifically, the jump near operand is relative with CS segment, ex. jmp near 0004h which the processor will jmp to addess CS:0004h. Now, because no one ever stated any standard to set at a particular segment, CS is ambigous on differnt systems. Which means if the BIOS runs the boot sector with CS=0, your boot sector will run into problems, while a jmp far before hand to set CS would assure that its on the right track.
Near jumps work relative to IP and the encoded operand is a signed word. Doing JMP near 0004h with the instruction assembled to address 0000h will encode the jump to hop 4 bytes ahead of the first byte of the jump instruction regardless of the actual offset that the code is loaded at, the word operand will have a value of 1.
Short jumps are a shorter version with a signed byte instead, except that since this form is one byte shorter the encoded operand would have to be 2 since it is relative to the IP while the jump is being executed, which points to the byte after the jump instruction itself.
You weren't clear on this and I wanted to make sure you knew near jumps don't encode absolute offsets. The 3 byte size of a near jump is the same as the 3 byte area before the BPB because you may want to jump further than 127 bytes ahead in one hop, which is possible to want since the sector is 512 bytes.
Re:Question about boot sector
Posted: Sun Jun 25, 2006 10:45 am
by Ryu
blip wrote:
Near jumps work relative to IP and the encoded operand is a signed word. Doing JMP near 0004h with the instruction assembled to address 0000h will encode the jump to hop 4 bytes ahead of the first byte of the jump instruction regardless of the actual offset that the code is loaded at, the word operand will have a value of 1.
Short jumps are a shorter version with a signed byte instead, except that since this form is one byte shorter the encoded operand would have to be 2 since it is relative to the IP while the jump is being executed, which points to the byte after the jump instruction itself.
Yes your right, there is a near jump that is relative with IP. However theres also absolutes, I'm just mentioning the relevant information as its going a bit off topic.
There are two types of near jumps, there is the relative that you mention that assemblers (infact its the linker) will calculate that preforms a indirect jump, and theres the absolutes which is done from a memory pointer or register. If you don't do any of this then it has no effect with an ambiguous CS, I've recommended a safe code that will solve every jmp/call if he uses them. Near calls also have the two types, which now that I think of it would of served to be a better instruction to talk about. In near call cases, you may isolate yourself to only use relative versions but you will have to make an absolute return one way or another that will run into problems.
Heres the differnt near jumps and its opcodes:
E9 cw JMP rel16 Jump near, relative, displacement relative to next instruction
E9 cd JMP rel32 Jump near, relative, displacement relative to next instruction
FF /4 JMP r/m16 Jump near, absolute indirect, address given in r/m16
FF /4 JMP r/m32 Jump near, absolute indirect, address given in r/m32
blip wrote:
You weren't clear on this and I wanted to make sure you knew near jumps don't encode absolute offsets. The 3 byte size of a near jump is the same as the 3 byte area before the BPB because you may want to jump further than 127 bytes ahead in one hop, which is possible to want since the sector is 512 bytes.
I have stated that there can be a short jump followed by a
nop or a near jmp in that 3 bytes, so a near jump in the first 3 bytes is nothing to be a concern of,
only if the jump is to a label. However I'm not sure if its effected with what Chase is saying about jmp short + nop being a signature itself.
edit: Corrected some sentenses that may lead to more confusions.