OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Dec 11, 2017 9:07 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: bios not loading bootloader at 0000:7c00
PostPosted: Sun Nov 05, 2017 2:05 pm 
Offline

Joined: Sun Nov 05, 2017 1:46 pm
Posts: 13
I have a boot.asm file with the following content:
Code:
[ORG 0x7c00]
mov ah , 0x0e
mov al ,'X'
int 0x10
jmp 0x7c00

times 510 - ( $ - $$ ) db 0
dw 0xaa55

Then I compile with this command:
Code:
nasm boot.asm -f bin -o boot.bin

and execute in a virtual machine with this command:
Code:
qemu-system-i386 boot.bin

As expected, the screen is filled up with 'X'. However, this doesn't happen when I don't explicitly tell the bootloader to be loaded in 0x7c00 with [ORG 0x7c00]:
Code:
mov ah , 0x0e
mov al ,'X'
int 0x10
jmp 0x7c00

times 510 - ( $ - $$ ) db 0
dw 0xaa55

In the Babystep1 tutorial in OSDev Wiki (http://wiki.osdev.org/Babystep1) says:
Quote:
The CPU starts in real mode and the BIOS loads this code at address 0000:7c00

Why do I have to write
Code:
[ORG 0x7c00]
if the BIOS is supposed to load the code in that location anyways?


Last edited by 4dr14n31t0r on Sun Nov 05, 2017 5:48 pm, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00 with qemu
PostPosted: Sun Nov 05, 2017 3:36 pm 
Offline
Member
Member

Joined: Tue Feb 11, 2014 4:59 pm
Posts: 36
Code:
[ORG 0x7C00]

This is for compilator to calculate jumps and labels positions in your code.

Try this:
Code:
[ORG 0x7C00]
main:
   jmp   0x0000:.repair_cs
.repair_cs:
   {your code in here}

_________________
wataha.net - system programming, my own 64 bit kernel and software.


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00 with qemu
PostPosted: Sun Nov 05, 2017 3:47 pm 
Offline
Member
Member

Joined: Thu May 19, 2011 5:13 am
Posts: 204
4dr14n31t0r wrote:
Why do I have to write
Code:
[ORG 0x7c00]
if the BIOS is supposed to load the code in that location anyways?
That's why it has to be done, (so that the assembler knows), otherwise the default is org 0x0000.
Code:
00000000: B4 0E          mov ah , 0x0E
00000002: B0 58          mov al ,'X'
00000004: CD 10          int 0x10
00000006: E9 F7 7B       jmp 0x7C00 ; this jump is relative to 0x0000
Try this:
Code:
00000000: B4 0E           mov ah , 0x0E
00000002: B0 58           mov al ,'X'
00000004: CD 10           int 0x10
00000006: EA 00 7C 00 00  jmp 0x0000:0x7C00 ; this jump is absolute far

_________________
Mike Gonta
look and see - many look but few see

http://mikegonta.com


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00 with qemu
PostPosted: Sun Nov 05, 2017 3:52 pm 
Offline
Member
Member

Joined: Thu May 19, 2011 5:13 am
Posts: 204
akasei wrote:
Try this:
Code:
[ORG 0x7C00]
main:
   jmp   0x0000:.repair_cs
.repair_cs:
   {your code in here}
That's only for assemblers which use org for filling in gaps (MASM, TASM, AS).
FASM, for example allows multiple orgs within a file and works the same as NASM to inform the assembler where the code is located.

_________________
Mike Gonta
look and see - many look but few see

http://mikegonta.com


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00 with qemu
PostPosted: Sun Nov 05, 2017 5:26 pm 
Offline

Joined: Sun Nov 05, 2017 1:46 pm
Posts: 13
Sorry I copied and pasted the wrong code. In the first code it should be "jmp 0x7c00" instead of "jmp 0x0". Now that post is edited and fixed.
If I have understood it correctly, when doing that relative jump I was jumping to 0xF800 because 0x7C00 x 2 = 0xF800. Am I correct?

_________________
Sorry if I commit some mistakes writting english. It is not my native language. If you find a typo in my posts, send me a PM


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00
PostPosted: Sun Nov 05, 2017 7:15 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1037
Location: Athens, GA, USA
No, because it isn't a relative jump. The presence of the segment prefix (the 'cs' part) makes it is a 20-bit FAR jump, an absolute jump computed from the segment base and the segment offset by adding them at a 4-bit shift, like so:

Code:
bbbb0
0SSSS
--------
AAAAA


So, for a segment base of 0000 and an offset of 0x7x00, this would be:

Code:
0x00000
0x07c00
--------
0x07c00


However, this addressing system means that segments are no disjoint - for successive bases, the overlap by 16 bytes. This means that the same address can be represented as 0000:7c00, or 0001:7bf0, or 0010:7b00, or 0100:6c00, or even 07c0:0000. I will get to this part more a bit later.

Without the segment prefix, this still wouldn't be an IP-relative jump, however. The CS (Code Segment) segment register is one of four used in real mode, and is the default for code addresses. In real mode, the default JMP instruction without a segment prefix is a 16-bit NEAR jump, which is relative to the segment base address held in CS, not relative to the instruction pointer - that is to say, it is a jump to cs:0x7c00, whatever CS might currently be. This means that the target of a FAR jump with the CS segment prefix is the exact same as a NEAR jump to the same offset - provided that the base in CS is the same as that which is used for the origin of the assembled label being jumped to. Again, I'll get back to this in a moment.

There is an 8-bit SHORT jump, which is a signed IP-relative jump (i.e., it can jump back up to 127 bytes, or forward up to 128 bytes) but with most assemblers, you would need to explicitly state it as SHORT:

Code:
    jmp short .somewhere


Note that conditional jumps in real mode are different - all conditional jumps in the original 8086 were short IP-relative. Also, in 32-bit protected mode, the same opcode is used for 16-bit IP-relative jumps instead.

Now, if the BIOS is properly standards-compliant, at the boot entry point CS should be 0000, which means that if the code is assembled with an origin of 7c00, the code addresses computed by the assembler should. However, that standard didn't get formalized until the late 1990s, specifically as part of the PC98 standard IIRC. Prior to this, most BIOSes did do it that way, but there were a few BIOS implementations which had a different starting CS (usually 07c00, making the entry point the same absolute address but mangling the assembled addresses), which is why many older tutorials on boot loaders recommend that you use a FAR jump to force CS to whatever base you have set the assembled origin at.

That's what the jump you copied there is meant to do, but, well... it shouldn't be needed anymore. Not for any PC-compatible made in the past 20 years, at any rate.

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
μή εἶναι βασιλικήν ἀτραπόν ἐπί γεωμετρίαν
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00
PostPosted: Sun Nov 05, 2017 8:00 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8168
Location: At his keyboard!
Hi,

Schol-R-LEA wrote:
That's what the jump you copied there is meant to do, but, well... it shouldn't be needed anymore. Not for any PC-compatible made in the past 20 years, at any rate.


If someone tries to boot your OS on an ancient computer from 1980 your boot code should behave correctly (e.g. correctly display a "Your CPU is too old" error message without crashing, and correctly halt and wait for user to reboot without crashing). ;)


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00
PostPosted: Mon Nov 06, 2017 3:28 am 
Offline
Member
Member
User avatar

Joined: Thu Mar 10, 2016 7:35 am
Posts: 130
Location: Lancaster, England, Disunited Kingdom
I'm not sure what schol-R-Lea meant by "the default jump" in his post, but the example in the OP's code snip:

00000006: E9 F7 7B jmp 0x7C00 ; this jump is relative to 0x0000

though requested as an absolute jump is actually coded as a near jump relative to the next instruction, not the segment base.

It is written by the programmer as if its an absolute jump (to 0x7c00) but the assembler converts this absolute address into a relative one and it is that converted value which appears as the machine coding:

E9 Jmp near relative to next instruction
0x7BF7 relative jump (bytes actually are coded f7 7b in usual Intel convention)
Next instruction is at 0x9
0x9+0x7bf7 = 0x7c00 as requested by the programmer.

This is why the ORG statement is required so that he assembler knows how to convert the absolute address requested to the relative value required in the output code.


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00
PostPosted: Mon Nov 06, 2017 3:37 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3025
Location: Chichester, UK
I'm not sure that this has been made sufficiently clear:

The ORG directive is not telling the computer where to load the program. It is the other way round - the ORG directive is telling the assembler that this is where the program will be loaded. (It's always loaded at that address, whatever ORG directives you use.)


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00
PostPosted: Mon Nov 06, 2017 4:13 am 
Offline

Joined: Sun Nov 05, 2017 1:46 pm
Posts: 13
Sorry for the misunderstanding. mikegonta wrote in Sun Nov 05, 2017 3:47 pm this code:
Code:
00000000: B4 0E          mov ah , 0x0E
00000002: B0 58          mov al ,'X'
00000004: CD 10          int 0x10
00000006: E9 F7 7B       jmp 0x7C00 ; this jump is relative to 0x0000

And then I wrongly said 'relative jump' but I mean relative to 0x0000

_________________
Sorry if I commit some mistakes writting english. It is not my native language. If you find a typo in my posts, send me a PM


Top
 Profile  
 
 Post subject: Re: bios not loading bootloader at 0000:7c00
PostPosted: Mon Nov 06, 2017 8:40 am 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1037
Location: Athens, GA, USA
MichaelFarthing wrote:
I'm not sure what schol-R-Lea meant by "the default jump" in his post,


I meant a JMP instruction without adding an explicit SHORT/NEAR/FAR modifier, in MASM/NASM syntax. That assumption of MASM syntax was careless of me.

MichaelFarthing wrote:
but the example in the OP's code snip:


This was careless of me, too. I had gotten turned around and was looking at the code snippets given by akasei and MikeGonta, both of which used absolute FAR jumps on a constant immediate segment base, then somehow go further confused and started thinking that they were using 'cs:' as the base instead of '0x0000'.

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
μή εἶναι βασιλικήν ἀτραπόν ἐπί γεωμετρίαν
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 13 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