[SeaBIOS] 16 Segementation help

Daniel Castro evil.dani at gmail.com
Thu Mar 15 11:33:10 CET 2012


Kevin, I greatly appreciate your help. Sorry to bother you again.

Could you please check the following sample code, I am sure I am doing
something wrong, but I am on the right path:

I have:
struct xendrive_s * xd = conteiner_of(op->drive_g,...)
struct blk_info * bi = GLOBALFLAT2GLOBAL($(GET_GLOBALFLAT(xd)->info);
To test I do:
dprintf(1,"DEBUG test xendrive %p and an int
%d.\n",GET_GLOBALFLAT(xd),GET_GLOBALFLAT(GET_GLOBALFLAT(bi)->buffer_gref));

The result is that the address is something like:
DEBUG test xendrive 0xf000ff53 and an int -16310017.
It should have been 0x000fd630 and an int 4.

I know there are several ways to represent the same address using
segmentation. Some clues on my mistakes please?

Thanks a million.
Daniel

On Wed, Mar 14, 2012 at 9:20 AM, Kevin O'Connor <kevin at koconnor.net> wrote:
> On Tue, Mar 13, 2012 at 06:44:19PM +0900, Daniel Castro wrote:
>> Hello,
>>
>> Sorry to bring this again, but I am still struggling with 16 bit disk operation.
>>
>> This time I have a simpler question.
>>
>> When I do container_of(...) I get pointer to 0xd630.
>> The address when I created the drive struct is 0x000fd630.
>> What do I need to do to be able to use the return of container_of in 16bit code?
>
> When in "segmented" mode (both 16bit mode and 32bit segmented mode)
> the processor does not have a uniform view of memory.  This is quite
> complex and painful to work with, so basically no modern systems use
> it anymore.  For compatibility, seabios must still support 16bit mode
> though.  This means that when it is in segmented mode it has a
> different view of memory than the init code (which runs in regular
> 32bit flat mode).
>
> So, the following code:
>
> u8 myglobal VAR16VISIBLE;
> ...
>    dprintf(1, "myglobal addr = %p\n", &myglobal);
>
> Will show two different results - it prints 0xf1234 in 32bit flat mode
> (it's a variable in the f-segment).  In 16bit mode it shows up as
> 0x1234 - the build arranges for this in order to keep the address
> within a 16bit range.  To access the variable in 16bit mode, one must
> use GET_GLOBAL(myglobal) - this will arrange for the proper segment
> accessor (in this case %cs) to be used in conjunction with the
> variable address (eg, 0x1234) to load the proper value.
>
> However, the following code:
>
> int *myptr VAR16VISIBLE;
> ...
>   myptr = malloc_fseg(16);
> ...
>   dprintf(1, "myptr = %p\n", GET_GLOBAL(myptr));
>
> The dprintf will show 0xf4567 regardless of the mode it is in.  That
> is because the pointer is loaded up at runtime with a 32 bit flat
> address, and the build has no way of "fixing" that up.  To access the
> content of the pointer, one would use the GET_GLOBALFLAT() macro.
>
> To make things slightly more complex, a *drive_g pointer returned from
> block.c:getDrive() makes the conversion from GLOBALFLAT to GLOBAL (via
> the GLOBALFLAT2GLOBAL macro.  So, if you're working with drive_g
> pointers, you should just use GET_GLOBAL.  This, BTW, is the reason
> for the "_g" and "_gf" sufixes found in places through the code -
> they're identifiers for pointers that are global vs globalflat.
>
> Also, be aware that *every* pointer access (that isn't pointing to a
> variable on the stack) must be wrapped in a macro.  Failure to do this
> will result in random data being read.  As an example of this, to read
> the integer pointed to by the global variable "myptr" above, one would
> need to run GET_GLOBALFLAT(*GET_GLOBAL(myptr)) - one macro to extract
> the global variable and the other macro to extract the data pointed to
> by the global variable.
>
> So, basically, pointers have to be accessed the correct way in order
> for the system to work.  I know this is complex, but it's just the
> reality of programming in segmented mode.  This complexity has nothing
> to do with container_of - that macro works the same way regardless of
> the mode.
>
> -Kevin



-- 
+-=====---------------------------+
| +---------------------------------+ | This space intentionally blank
for notetaking.
| |   | Daniel Castro,                |
| |   | Consultant/Programmer.|
| |   | U Andes                         |
+-------------------------------------+



More information about the SeaBIOS mailing list