[OpenBIOS] Help with libopenbios/ofmem_common.c line 175 "insert in the freelist"

Kenneth Salerno kennethsalerno at yahoo.com
Thu Aug 11 00:23:12 CEST 2011


--- On Tue, 8/9/11, Mark Cave-Ayland <mark.cave-ayland at siriusit.co.uk> wrote:

> From: Mark Cave-Ayland <mark.cave-ayland at siriusit.co.uk>
> Subject: Re: [OpenBIOS] Help with libopenbios/ofmem_common.c line 175 "insert in the freelist"
> To: openbios at openbios.org
> Date: Tuesday, August 9, 2011, 9:43 AM
> On 08/08/11 22:40, Kenneth Salerno
> wrote:
> 
> > Hi,
> > 
> > I finally got around to running QEMU in gdb to debug
> the AIX V6.1 boot hang and was able to get past where I got
> stuck previously:
> > 
> >
> -------------------------------------------------------------------------------
> >               
>                
>    Welcome to AIX.
> >               
>          boot image timestamp:
> 00:39 35/2D
> > NULL ihandle           
>      The current time and date: 00:00:00
> 228784/00/0008
> >          processor count:
> 1;  memory size: 1024MB;  kernel size: 2293829
> >               
>       boot device: cd:\ppc\chrp\bootfile.exe
> > Validation failed: the "/rtas" device node does not
> exist.
> > EXIT
> > 
> > 
> > It used to hang after "boot device:
> cd:\ppc\chrp\bootfile.exe" with OpenBIOS stuck at line 175
> of libopenbios/ofmem_common.c:
> > 
> >    for( pp=&ofmem->mfree;
> *pp&&  (**pp).size<  d->size ; pp
> =&(**pp).next ) {
> >    }
> > 
> > 
> > I made the following hack to get it to progress to the
> RTAS validation:
> > 
> > --- ofmem_common.c.ORIG 2011-08-08 17:04:25.375000000
> -0400
> > +++ ofmem_common.c      2011-08-08
> 17:04:45.875000000 -0400
> > @@ -172,8 +172,9 @@
> >          d->next =
> ofmem->mfree;
> > 
> >          /* insert in the
> (sorted) freelist */
> > -       for(
> pp=&ofmem->mfree; *pp&& 
> (**pp).size<  d->size ; pp =&(**pp).next
> > ) {
> > -       }
> > +/*     for(
> pp=&ofmem->mfree; *pp&& 
> (**pp).size<  d->size ; pp =&(**pp).next
> > ) {
> > +       } */
> > +   
>    pp=&ofmem->mfree;
> > 
> >          d->next = *pp;
> >          *pp = d;
> > 
> > 
> > Before I made the above change, the following is what
> I saw in gdb and qemu console:
> > 
> >    (qemu) info cpus
> >    * CPU #0: nip=0x00000000fff91a84
> thread_id=6828
> > 
> >    (gdb)
> >    0x00000000fff91a84 in ofmem_free
> (ptr=0x3fca1774)
> >        at
> ../libopenbios/ofmem_common.c:175
> >    175   for(
> pp=&ofmem->mfree; *pp&& 
> (**pp).size<  d->size ; pp =&(**pp).next ) {
> > 
> >    (gdb) print /x pp
> >    $1 = 0x3fc9e0ac
> > 
> > The value 0x3fc9e0ac can be found in register GPR08:
> > 
> >    (qemu) info registers
> >    NIP 00000000fff91a84   LR
> 00000000fff91a58 CTR 00000000fff93784 XER 000000002000
> > 0000
> >    MSR 0000000000003032 HID0
> 0000000060000000  HF 0000000000002000 idx 1
> >    TB 00000001 7638146663 DECR 951787926
> >    GPR00 000000003fca1764 000000003fdf69e0
> 00000000fffc68e8 000000003fc9e0ac
> >    GPR04 00000000fffc0088 000000003fc5bc68
> 00000000fffc0860 0000000000044200
> >    GPR08 0000000000000002 000000003fc9e0ac
> 0000000000000024 0000000000000810
> >    GPR12 00000000000088ac 0000000000000000
> 00000000fffb6703 00000000fffb7b65
> >    GPR16 00000000fffb8331 00000000fffb6706
> 0000000004000000 00000000fffbf6b8
> >    GPR20 00000000fffbf634 00000000fffc68e8
> 00000000fffbf634 00000000fffb650a
> >    GPR24 00000000fffb64f8 00000000fffb6478
> 00000000fffb6500 00000000fffb6505
> >    GPR28 00000000fffb707e 0000000000000027
> 0000000000000027 000000003fca1774
> >    CR 48000084  [ G  L 
> -  -  -  -  L  G  ] 
>            RES
> ffffffffffffffff
> >    FPR00 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPR04 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPR08 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPR12 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPR16 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPR20 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPR24 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPR28 0000000000000000 0000000000000000
> 0000000000000000 0000000000000000
> >    FPSCR 00000000
> >    SRR0 00000000fffaa590  SRR1
> 0000000000003032    PVR 00000000003c0301 VRSAVE
> 000
> >    0000000000000
> >    SPRG0 000000003fe00000 SPRG1
> 000000003fdf6630  SPRG2 0000000000000000  SPRG3
> 000
> >    0000000000000
> >    SPRG4 0000000000000000 SPRG5
> 0000000000000000  SPRG6 0000000000000000  SPRG7
> 000
> >    0000000000000
> >    SDR1 000000003fe00000
> > 
> > 
> > Here is my QEMU command:
> > 
>>    ./testing/qemu/ppc64-softmmu/qemu-system-ppc64
> \
> >             -L
> ./testing/qemu/pc-bios \
> >             -m
> 1024 \
> >         
>    -bios
> ./testing/openbios-devel/obj-ppc64/openbios-qemu.elf
> >         
>    -drive
> file=images/aix.img,index=0,media=disk,cache=writeback
> >         
>    -cdrom images/ibmaix.iso \
> >         
>    -boot d \
> >         
>    -nographic \
> >         
>    -rtc base=localtime,clock=host \
> >         
>    -uuid 17202d0a-45f8-4159-a8e1-78b866f50aa7
> \
> >         
>    -serial tcp::9979,server,nowait \
> >         
>    -monitor tcp::9980,server,nowait \
> >         
>    -gdb tcp::1234
> > 
> >    powerpc64-unknown-linux-gnu-gdb
> testing/openbios-devel/obj-ppc64/openbios-qemu.elf-nostrip
> > 
> > I don't really know what I'm doing so any help
> explaining this function in ofmem_common.c would be
> appreciated.
> 
> Hi Ken,
> 
> I didn't write the original version of this code, however I
> have played around with it enough to get an idea of what it
> does, so hopefully the explanation below will make sense ;)
> 
> ofmem_malloc() and ofmem_free() are mapped to malloc() and
> free() calls used within OpenBIOS. They are not used by any
> client program. If an area of memory is requested via CIF
> then the allocation is handled separate using the arch/*/
> OFMEM code which will handle memory allocations/mapping
> across the entire address range.
> 
> As per the code in libopenbios/ofmem_common.c,
> ofmem_malloc() allocates memory within the OpenBIOS binary
> image between ofmem_arch_get_malloc_base() and
> ofmem_arch_get_heap_top(). These limits are also specified
> per architecture within the arch/*/ OFMEM handler.
> 
> In order to facilitate memory re-use, if a chunk of memory
> is ofmem_free()d then it is added to a free memory
> linked-list starting at ofmem->mfree ordered by size. The
> ofmem_malloc() code at line 105 consults this list first
> when trying to allocate memory in order to try and ensure
> that repeated ofmem_malloc() and ofmem_free() calls on the
> same size area of memory don't deplete the available memory
> store.
> 
> Finally, ofmem_malloc() must ensure that the returned
> pointer is aligned both physically and virtually, and the so
> the memory descriptor for an entry is stored just before it
> in memory like this:
> 
> 
>                
>   | <- aligned ptr
>    ----------------------------------------
>    | alloc_desc_t | region (<size>
> bytes) |
>    ----------------------------------------
> 
> 
> The code you are having trouble with is the code that tries
> to add the ofmem_free() location back into the freelist
> starting at ofmem->mfree.
> 
> Now if ofmem->mfree is getting clobbered somehow then
> that would cause the linked list to jump to random locations
> in memory and hence cause a crash. In these cases the tactic
> is to add a watchpoint in gdb at ofmem->mfree so that gdb
> breaks whenever that memory location is written to. Assuming
> you compile OpenBIOS with -O0 -g then you can obtain a
> backtrace in order to find out where the error is occurring
> and post it back to the list if you need further help.
> 
> 
> HTH,
> 
> Mark.
> 
> -- Mark Cave-Ayland - Senior Technical Architect
> PostgreSQL - PostGIS
> Sirius Corporation plc - control through freedom
> http://www.siriusit.co.uk
> t: +44 870 608 0063
> 
> Sirius Labs: http://www.siriusit.co.uk/labs
> 

Thanks for the information, Mark.

I'm having issues getting OpenBIOS to work properly when I disable optimization, and I'm sure it's something I'm doing wrong or my compiler has a bug (GCC 4.6.1).

If I change -O2 to -O0 in Makefile.target, execution in QEMU will hang with a next instruction pointer of 0x0000000000000004 while reading the IDE device inside the Forth code... If I compile with -02, as you already know, I am told by GDB that ofmem->mfree was optimized out and cannot set a watchpoint:

#0  0x00000000fff91a84 in ofmem_free (ptr=0x3fca1774)
    at ../libopenbios/ofmem_common.c:175
#1  0x00000000fff8862c in free (ptr=<optimized out>)
    at ../arch/ppc/qemu/ofmem.c:258
#2  0x00000000fff93798 in deblk_close (di=<optimized out>)
    at ../packages/deblocker.c:66
#3  0x00000000fff8d950 in call1_func () at ../libopenbios/bindings.c:431
#4  0x00000000fff8b62c in call () at ../kernel/forth.c:244
#5  0x00000000fff8b4e8 in processxt (xt=<optimized out>)
    at ../kernel/forth.c:106
#6  next () at ../kernel/forth.c:127
#7  0x00000000fff8d288 in enterforth (xt=<optimized out>)
    at ../kernel/forth.c:156
#8  0x00000000fff8de7c in _selfword (method=0xfffb7d26 "close-deblocker",
    cache_xt=0xfffc0088) at ../libopenbios/bindings.c:83
#9  0x00000000fff98478 in ob_ide_close (drive=<optimized out>)
    at ../drivers/ide.c:1289
#10 0x00000000fff8d950 in call1_func () at ../libopenbios/bindings.c:431
#11 0x00000000fff8b62c in call () at ../kernel/forth.c:244
#12 0x00000000fff8b4e8 in processxt (xt=<optimized out>)
    at ../kernel/forth.c:106
#13 next () at ../kernel/forth.c:127
#14 0x00000000fff8d288 in enterforth (xt=<optimized out>)
    at ../kernel/forth.c:156
#15 0x00000000fff8daec in _fword (word=<optimized out>, cache_xt=0xfffbfec0)
    at ../libopenbios/bindings.c:71
#16 0x00000000fff8f20c in of_client_interface (params=0x44200)
    at ../libopenbios/client.c:318
#17 0x00000000fff019fc in of_client_callback ()
    at ../arch/ppc/qemu/start.S:614
Backtrace stopped: frame did not save the PC

Sorry to bug you but why can't I get a working OpenBIOS ELF with compiler optimization disabled?

Thank you,
Ken



More information about the OpenBIOS mailing list