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 <[email protected]> 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 | +-------------------------------------+ _______________________________________________ SeaBIOS mailing list [email protected] http://www.seabios.org/mailman/listinfo/seabios
