Page 1 of 1

Efficiently loading os

Posted: Wed Mar 21, 2007 8:54 pm
by billion_boi
hey, my question is if a bootloader is loaded segment 0000 offsett 07c00 and is 512 bytes long, how do i find the end segment/offsett? I want to know because i want to load my second stage directly from that point, without wasting any memory space...

Since a segment is 64kb in realmode, that would mean i should still be in the first one by the end of th first stage bootloader.

Posted: Thu Mar 22, 2007 3:32 am
by AJ
Hi,

If your boot sector is 512b long (0x200) and is loaded at 0x0000:0x7c00, you can load your next stage at starting at 0x0000:0x7e00.

Cheers,
Adam

Posted: Thu Mar 22, 2007 2:17 pm
by billion_boi
thanks alot, do you know of a tutorial that can help me calculate that for future refrence

Posted: Thu Mar 22, 2007 2:25 pm
by AJ
erm - add 0x200 hex to 0x7c00 hex?

If you aren't at home with hex, you could always use a conversion program. However, when you're dealing with representations of binary numbers, hex is much easier - I'd try to get comfortable with it.

You could always try http://www.easycalculation.com/hex-converter.php. If you are using Windows, start calculator, put it in scientific mode and get to know the shortcuts (F5-F8 change the notation). If you are using linux, I'm sure someone else can tell you what to use.

But really, after a little OS programming, you will be as comfortable in hex as decimal and binary.

Cheers,
Adam

Posted: Thu Mar 22, 2007 2:31 pm
by AJ
Oh - and if your problem is with segments, just remember that in *real mode*, to convert to a linear address, you just multiply the segment by 0x10 (16 decimal) and add to the offset, so:

0x0001:0xabcd --> 0x0010 + 0xabcd = 0xabdd
0x00c0:0x7000 --> 0x0c00+0x7000 = 0x7c00
0x0020:0x7a00 --> 0x0200+0x7a00 = 0x7c00

[praysmathsisright]

So note that the same linear address can have many different segment:offset notations - the last 2 examples give exactly the same result.

Maximum address in real mode is therefore:

0xFFFF:0xFFFF --> 0xFFFF0+0xFFFF = 0x10FFEF

Adam

Posted: Thu Mar 22, 2007 3:02 pm
by billion_boi
My mistake, what i meant to ask is what is the max size of an offsett befor a new segment begins.

But i think a figured it out since a segment is 64kb big that makes it 65536 bytes large which when coverted to hex is 10000
So any value higher than 0x0000:0x10000 should start a new segment
ex. 0x0001:0x0001
Am i right?

Posted: Thu Mar 22, 2007 4:55 pm
by Candy
billion_boi wrote:My mistake, what i meant to ask is what is the max size of an offsett befor a new segment begins.

But i think a figured it out since a segment is 64kb big that makes it 65536 bytes large which when coverted to hex is 10000
So any value higher than 0x0000:0x10000 should start a new segment
ex. 0x0001:0x0001
Am i right?
The segments in real mode overlap - a new segment starts every 16 bytes. A segment is 65536 bytes long though.

So, 0x7C0:0x0000 refers to the exact same location (!) as 0x0000:0x7C00.

If you use a 32-bit offset in real mode (plain) you get an exception. If you use a 32-bit offset in unreal mode, it works as a linear offset to the base of the segment (although unreal mode messes with the segments a bit). However, if you truly use real mode and increment ax (when it's 0xFFFF) by 1, you get 0x0000, not 0x10000. The 1 can't be stored, it's put in the carry bit and ignored if you don't pay attention to it.

Posted: Thu Mar 22, 2007 9:03 pm
by billion_boi
Ok so from what i can understand i made a visual, could someone let me know if its correct? Its attached

Posted: Fri Mar 23, 2007 12:21 am
by mystran
If you have a segment offset pair DEAD:BEEF, then you can calculate the effective address in memory as:

Code: Select all

 DEAD0
+ BEEF
------
 EA9BF 
You could theoretically use that to get a bit over 1MB, but A20 line being disabled by default will wrap you back to 0 if you ever get a 6-hexadecimals long address.. until ofcourse you enable A20 to do something useful in protected mode..

Posted: Fri Mar 23, 2007 2:32 am
by AJ

Posted: Sun Mar 25, 2007 1:24 pm
by Candy
billion_boi wrote:Ok so from what i can understand i made a visual, could someone let me know if its correct? Its attached
Small tidbit on your notation: It's common to use the prefix k (small K) for kilo as in 1024. The SI-compliant would be k for 1000 or ki (kibi) for 1024. Also, people use b (small B) for bits and B (large B) for bytes, that's going to confuse people if they look at your image. So:

kB = 1024 bytes (old definition)
kB = 1000 bytes (new definition)
kb = 125 bytes / 1000 bits (new definition)
kib = 128 bytes
kiB = 1024 bytes

The secret is in the details.

Posted: Sun Mar 25, 2007 1:51 pm
by billion_boi
Aj, that website explained it all really well, thanks for taking the time to post it up, and same to you candy, i saved your notes for future refrence. :)

Posted: Mon Mar 26, 2007 4:03 am
by AJ
No worries - I had some conceptual problems with real mode segments when I started rolling my own boot loader. Of course, now I use GRUB, it doesn't matter any more :) (until I start using v86 for switching video modes :? )

Adam