OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 4:41 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: New here, trying to understnad segments and bootloaders.
PostPosted: Tue Apr 09, 2019 7:41 pm 
Offline

Joined: Tue Apr 09, 2019 12:34 pm
Posts: 13
JAAman wrote:
Quote:
Something that tricked me:
If 0x7c is the actual physical memory where my program is getting loaded, how does ORG = 0x7c is an offset from the beginning of the segment to the head of my program? Doesn't that mean that the segment starts from memory 0x0?

it does if you set the segment register to 0 (like you are doing with DS) -- note though that you can only access the first 64KB of memory without changing DS to something different (in normal RMode, your offset, and thus your ORG also, will always be less than 64K)

because DS.base == 0, your ORG is the same as the address you are loading to, but if your DS.base != 0, then your ORG would not be the same as the loading address


Oh :P I was thinking that ORG was the offset from the CS.base to the start of my program. I read your post where you said about it and I found out I missed that you where saying from the DS.base to the head of my program.

Now I get everything!!! Thank you so much!
Well, I'll certainly be back with more questions when I move further in learning about OSes.


Top
 Profile  
 
 Post subject: Re: New here, trying to understnad segments and bootloaders.
PostPosted: Tue Apr 09, 2019 8:03 pm 
Offline

Joined: Tue Apr 09, 2019 12:34 pm
Posts: 13
I tried removing the ORG and I also updated the loader label as followed:
Code:
loader:
   mov   ax, 0x7c*16
   mov   ds, ax
   mov   es, ax


And it works!!! Just to see if I understand everything correctly.


Top
 Profile  
 
 Post subject: Re: New here, trying to understnad segments and bootloaders.
PostPosted: Wed Apr 10, 2019 3:44 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
You'd probably run into fewer issues if you use org 0x7c00 and set the segment registers to zero. This has the advantage that linear addresses (in real mode the same as physical ones) are the same. Offsets are relative to the beginning of memory. This is advantageous if you intend to create a GDT to be loaded with LGDT. The GDT record requires a linear address to the base of the GDT. If you use a non-zero segment like 0x7c0 then you have to adjust any linear addresses you may use by adding 0x7c00 to them.


Top
 Profile  
 
 Post subject: Re: New here, trying to understnad segments and bootloaders.
PostPosted: Sat Apr 13, 2019 2:07 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 18, 2007 7:28 pm
Posts: 1564
Hi,

Regarding the lack of segment .text... We don't use "segment .text" in the code because of its redundancy; .text is the default segment. It is also important to note that org 0 is the default origin value if not specified.

Regarding the org directive... Instructions that reference labels generate relocations that get added to the origin value. This is important for generating correct label addresses. Note this is an assembler directive and is only used to translate to correct code. For example:

Scenario 1: With org 0, segments set to 0x7c0...instructions like mov ax, ds:[myLabel] are translated as mov ax, ds:[myLabel+0]. Because ds is 0x7c0 this is 0x7c0:myLabel which is what we want. So org 0, ds=0x7c0 works.

Scenario 2: With org 0x7c00, segments set to 0...Instructions like mov ax, ds:[myLabel] are translated as mov ax, ds:[myLabel+0x7c00]. Because ds is 0, this is 0:myLabel+0x7c00=0x7c0:myLabel. So org 0x7c00, ds=0 works. This is what we do in the tutorial.

Scenario 3: With org 0x7c00, segments set to 0x7c0...Instructions like mov ax, ds:[myLabel] are translated as mov ax, ds:[myLabel+0x7c00]. Because ds is 0x7c0, this places myLabel at 0x7c0:myLabel+0x7c00, or 0xf80:myLabel which is well outside the boot record code. This would result in garbage data being loaded into ax - not what we want.

About the code... The code assumes the assembler translates "jmp loader" as a 3 byte near jump. However, with optimization, could be translated as a short jump which will cause problems with the BPB. It is recommended to be explicate; "jmp near loader" or "jmp short loader .. nop". Also, the code should not assume its actual load address. Right at the start of "loader", it should do a far jump or push/retf to fix it. Not doing so may cause unexpected behavior on systems that loads the code in a different segment then what your code expects (i.e. loading to 0:0x7c00 instead of 0x7c0:0.) Finally, to stop executing, cli and hlt should be in an infinite loop. I.e. "stop: cli .. hlt .. jmp stop". cli does not mask SMM and NMI's which can wake the system, so cli and hlt alone isn't enough.

_________________
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}


Top
 Profile  
 
 Post subject: Re: New here, trying to understnad segments and bootloaders.
PostPosted: Mon Apr 15, 2019 9:38 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 27, 2004 11:00 pm
Posts: 874
Location: WA
neon wrote:
Also, the code should not assume its actual load address. Right at the start of "loader", it should do a far jump or push/retf to fix it.

I cannot possibly disagree with this advise more strongly

the truth is, while it is true (as I stated in my previous posts) that you cannot know what CS:IP combination in use, it is also true (as I stated in my previous posts) that it doesn't matter what the CS:IP combination is
Quote:
Not doing so may cause unexpected behavior on systems that loads the code in a different segment then what your code expects (i.e. loading to 0:0x7c00 instead of 0x7c0:0.)

the only "unexpected behavior" that can possibly occur is IP wrapping around to zero before getting to the end of your code... which would only happen if CS was set to something really weird (like CS:IP == F7C1:FFF0)... which doesn't happen often enough to care about, and even when it does, it is safe enough to assume it can reach the end of the BPB -- that means, if you assume CS <= 0xF7C0 || CS >= 0xF7E0 (and half of those values would fail to boot DOS/Windows too) then there is no need to care what CS is

_________________
## ---- ----- ------ Intel Manuals
OSdev wiki


Top
 Profile  
 
 Post subject: Re: New here, trying to understnad segments and bootloaders.
PostPosted: Mon Apr 15, 2019 11:22 am 
Offline
Member
Member

Joined: Wed Mar 09, 2011 3:55 am
Posts: 509
JAAman wrote:
Quote:
Not doing so may cause unexpected behavior on systems that loads the code in a different segment then what your code expects (i.e. loading to 0:0x7c00 instead of 0x7c0:0.)

the only "unexpected behavior" that can possibly occur is IP wrapping around to zero before getting to the end of your code... which would only happen if CS was set to something really weird (like CS:IP == F7C1:FFF0)... which doesn't happen often enough to care about, and even when it does, it is safe enough to assume it can reach the end of the BPB -- that means, if you assume CS <= 0xF7C0 || CS >= 0xF7E0 (and half of those values would fail to boot DOS/Windows too) then there is no need to care what CS is


One spot where you would run into trouble is if your boot code uses an absolute indirect near jump rather than a relative near jump, but that's easily enough avoided.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2

All times are UTC - 6 hours


Who is online

Users browsing this forum: Amazonbot [bot], SemrushBot [Bot] and 50 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