Re: GRUB on OLPC / XO
On Mon, Jan 21, 2008 at 11:24:52AM +0100, Marco Gerards wrote: _start: 0x1, _end: 0x1f804 Using memory for heap: addr=0x10, end=0x40 Using memory for heap: addr=0x2000, end=0x9 Welcome to GRUB! See how our core image and the second heap chunk overlap. I'm not sure if this is a bug in OFW's /memory/available, but in any case it doesn't hurt to add a generic sanity check in our memory manager to avoid this sort of breakage. It's also be useful to protect our own stack, etc.. What do you think? At least some kind of check should be available. It could also be in init.c. Yep. I concluded that there's nothing usefuly portable about having this in kern/, and proposed: [PATCH] safety check in claim_heap() see my other mail below. -- Robert Millan GPLv2 I know my rights; I want my phone call! DRM What use is a phone call… if you are unable to speak? (as seen on /.) ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel
Re: GRUB on OLPC / XO
On Tue, Jan 15, 2008 at 12:31:30PM +0100, Marco Gerards wrote: Robert Millan [EMAIL PROTECTED] writes: Hi, I've been working for a few hours in a GRUB port to i386/OFW. There's quite a bit of things that need cleanup/fix before it can be considered complete, but it's in a stage that boots and lets you do basic things (like listing storage devices). OLPC is OF!? I didn't expect this :-). Who made the firmware? Mitch Bradley (author of Open Firmware). I'll be gradually integrating this into official GRUB tree. In the meantime, if you want to try it: - checkout GRUB cvs (grub2 module) - apply attached patch - ./autogen.sh ./configure --with-platform=ieee1275 make kernel.elf Great! I'll just review the patch! :-) Please don't. It's not meant for review, was just a proof of concept. The patches I actually intend to get merged are being sent separately (see my later mails on this). Oh well, too late.. :-) +COMMON_ASFLAGS = -m32 -nostdinc -fno-builtin +COMMON_CFLAGS = -ffreestanding -mrtd -mregparm=3 +COMMON_LDFLAGS = -nostdlib -static -lgcc Why mregparm? I don't think we need this for OF? Do you call assembler functions? OFW expects %eax to be the first parameter in callbacks. Other than this, I assumed -mregparm is a useful size optimization. Is that not it? Why do we have it on i386-pc then? /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); - grub_load_modules (); +// grub_load_modules (); Why? I still don't know. Memory corruption I think. I'm investigating. diff -x '*.mk' -x '*~' -x CVS -x .svn -x configure -x config.h.in -Nurp ../../grub2/kern/powerpc/ieee1275/cmain.c ./kern/powerpc/ieee1275/cmain.c --- ../../grub2/kern/powerpc/ieee1275/cmain.c 2007-12-30 09:52:05.0 +0100 +++ ./kern/powerpc/ieee1275/cmain.c 2008-01-12 03:12:01.0 +0100 @@ -58,7 +58,7 @@ grub_ieee1275_find_options (void) grub_ieee1275_finddevice (/options, options); rc = grub_ieee1275_get_property (options, real-mode?, realmode, sizeof realmode, 0); - if ((rc = 0) realmode) +// if ((rc = 0) realmode) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE); Ehm? Nothing to see here. Move along :-) - while (i sizeof (available)) + while (i sizeof (available) available[i]) { grub_uint64_t address; grub_uint64_t size; - address = available[i++]; + address = grub_be_to_cpu32 (available[i++]); Why do you do this? Isn't this information available in native byte order? See my other mail about IEEE-1275 and endianess. diff -x '*.mk' -x '*~' -x CVS -x .svn -x configure -x config.h.in -Nurp ../../grub2/term/ieee1275/ofconsole.c ./term/ieee1275/ofconsole.c --- ../../grub2/term/ieee1275/ofconsole.c 2007-12-25 12:10:47.0 +0100 +++ ./term/ieee1275/ofconsole.c 2008-01-12 03:09:02.0 +0100 @@ -369,9 +369,6 @@ static struct grub_term grub_ofconsole_t .getwh = grub_ofconsole_getwh, .gotoxy = grub_ofconsole_gotoxy, .cls = grub_ofconsole_cls, -.setcolorstate = grub_ofconsole_setcolorstate, -.setcolor = grub_ofconsole_setcolor, -.getcolor = grub_ofconsole_getcolor, Why do you do this? GRUB still wants to set light-gray/black color when run over serial port (or OFW terminal which could pipe to serial port). This is very ugly when your serial port is mapped to a black/white gnome-terminal. -- Robert Millan GPLv2 I know my rights; I want my phone call! DRM What use is a phone call, if you are unable to speak? (as seen on /.) ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel
Re: GRUB on OLPC / XO
On Tue, Jan 15, 2008 at 01:06:43PM +0100, Robert Millan wrote: /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); - grub_load_modules (); +// grub_load_modules (); Why? I still don't know. Memory corruption I think. I'm investigating. Ok, this would explain it: _start: 0x1, _end: 0x1f804 Using memory for heap: addr=0x10, end=0x40 Using memory for heap: addr=0x2000, end=0x9 Welcome to GRUB! See how our core image and the second heap chunk overlap. I'm not sure if this is a bug in OFW's /memory/available, but in any case it doesn't hurt to add a generic sanity check in our memory manager to avoid this sort of breakage. It's also be useful to protect our own stack, etc.. What do you think? -- Robert Millan GPLv2 I know my rights; I want my phone call! DRM What use is a phone call, if you are unable to speak? (as seen on /.) ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel
Re: GRUB on OLPC / XO
Some comments on things that need polishing. Some are more addressed at one of the two lists than the others, but feel free to join in either case. (also, if you feel this is off-topic in olpc-devel, feel free to ki^W let me know) btw, Mitch mentioned to me on IRC that the ELF loader on XO has some weird modifications to support Minix. Is this documented somewhere? On Sat, Jan 12, 2008 at 02:42:30PM +0100, Robert Millan wrote: +void +grub_exit (void) +{ + /* Trap to Open Firmware. */ + /* FIXME. */ + + for (;;); +} We used to run trap insttruction on powerpc. I assume for exitting via trap on i386 we need to generate an interrupt; I'm just not sure which is the right number for it. /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); - grub_load_modules (); +// grub_load_modules (); This generates an out of bounds exception. GRUB puts modules above _end (0x1000-aligned). Is access to that address allowed by OFW ? grub_ieee1275_finddevice (/options, options); rc = grub_ieee1275_get_property (options, real-mode?, realmode, sizeof realmode, 0); - if ((rc = 0) realmode) +// if ((rc = 0) realmode) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE); This OFW operates in what GRUB calls real mode (not to be confused with x86 realmode!), but /options/real-mode? doesn't exist. Should we probe for the actual feature (/chosen/mmu IIRC), probe for firmware version, or #ifdef it for x86 CPUs? -void cmain (uint32_t r3, uint32_t r4, uint32_t r5); void -cmain (UNUSED uint32_t r3, UNUSED uint32_t r4, uint32_t r5) +cmain (void) { - grub_ieee1275_entry_fn = (int (*)(void *)) r5; - This was the only powerpc-specific part of that file, that I can tell. I moved grub_ieee1275_entry_fn initialisation to startup.S. I'd suggest doing the same on powerpc/sparc and move cmain.c out of powerpc/ directory. diff -x '*.mk' -x '*~' -x CVS -x .svn -x configure -x config.h.in -Nurp ../../grub2/kern/powerpc/ieee1275/init.c ./kern/powerpc/ieee1275/init.c --- ../../grub2/kern/powerpc/ieee1275/init.c 2008-01-03 23:43:46.0 +0100 +++ ./kern/powerpc/ieee1275/init.c2008-01-12 03:26:06.0 +0100 @@ -52,15 +52,6 @@ grub_millisleep (grub_uint32_t ms) grub_millisleep_generic (ms); } -void -grub_exit (void) -{ - /* Trap to Open Firmware. */ - asm (trap); - - for (;;); -} Same here. /* Decode each entry and call `hook'. */ i = 0; - while (i sizeof (available)) + while (i sizeof (available) available[i]) Here we were attempting to claim a region that starts at 0x0 and ends at INT_MAX !! I suppose we just need to check for available property length. Need to look more into this. - address = available[i++]; + address = grub_be_to_cpu32 (available[i++]); if (address_cells == 2) - address = (address 32) | available[i++]; + address = (address 32) | grub_be_to_cpu32 (available[i++]); - size = available[i++]; + size = grub_be_to_cpu32 (available[i++]); if (size_cells == 2) - size = (size 32) | available[i++]; + size = (size 32) | grub_be_to_cpu32 (available[i++]); Integer properties are always in network byte order (thanks Mitch for clarifiing). I wonder if we should byteswap all callers of getprop or just mangle the result in the getprop function instead (the latter seems cleaner, but it wasn't obvious how to do it without breaking non-integer properties). Ah, and for some reason address_cells is set to a garbage number. Might be a pointer dereference issue, will look into this. --- ../../grub2/term/ieee1275/ofconsole.c 2007-12-25 12:10:47.0 +0100 +++ ./term/ieee1275/ofconsole.c 2008-01-12 03:09:02.0 +0100 @@ -369,9 +369,6 @@ static struct grub_term grub_ofconsole_t .getwh = grub_ofconsole_getwh, .gotoxy = grub_ofconsole_gotoxy, .cls = grub_ofconsole_cls, -.setcolorstate = grub_ofconsole_setcolorstate, -.setcolor = grub_ofconsole_setcolor, -.getcolor = grub_ofconsole_getcolor, .setcursor = grub_ofconsole_setcursor, .refresh = grub_ofconsole_refresh, .flags = 0, Not really a porting issue, but when using serial terminal GRUB still tries to set white/black color on it, which becomes very ugly in my black/white gnome-terminal :-) -- Robert Millan GPLv2 I know my rights; I want my phone call! DRM What use is a phone call, if you are unable to speak? (as seen on /.) ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel
Re: GRUB on OLPC / XO
Robert Millan wrote: Some comments on things that need polishing. Some are more addressed at one of the two lists than the others, but feel free to join in either case. (also, if you feel this is off-topic in olpc-devel, feel free to ki^W let me know) btw, Mitch mentioned to me on IRC that the ELF loader on XO has some weird modifications to support Minix. Is this documented somewhere? I was mistaken about Minix - there are no Minix-specific hacks in the ELF loader. The only Minix support is a handler for the Minix filesystem layout, which doesn't affect the ELF loader. The ELF loader has two special cases, which are not documented anywhere except the source code (cpu/x86/pc/olpc/linux.fth : ?memtest-elf-map-in ) : a) It recognizes the memtest86 binary that is embedded in OFW, setting up some special mappings that memtest requires (or at least used to require) b) It recognizes the ELF form of the Linux binary and sets up a mapping from virtual c0xx. to physical 00xx. . Normally this isn't used, because we load the bzImage version of Linux. But OFW can load the ELF portion of the Linux kernel, without the bzImage wrapper. If you do it that way, OFW has access to the ELF symbol table and can thus resolve symbolic names for addresses inside Linux. On Sat, Jan 12, 2008 at 02:42:30PM +0100, Robert Millan wrote: +void +grub_exit (void) +{ + /* Trap to Open Firmware. */ + /* FIXME. */ + + for (;;); +} We used to run trap insttruction on powerpc. I assume for exitting via trap on i386 we need to generate an interrupt; I'm just not sure which is the right number for it. To exit to OFW, call the exit() client service. To reboot, call boot() with an empty string as the single IN argument. To power off, call interpret() with a cmd string of power-off. /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); - grub_load_modules (); +// grub_load_modules (); This generates an out of bounds exception. GRUB puts modules above _end (0x1000-aligned). Is access to that address allowed by OFW ? The ELF loader will map in anything listed in a program header of type PT_LOAD , according to the vaddr, memsize, and filesize fields. If the module area is covered by such a program header, they should be accessible. grub_ieee1275_finddevice (/options, options); rc = grub_ieee1275_get_property (options, real-mode?, realmode, sizeof realmode, 0); - if ((rc = 0) realmode) +// if ((rc = 0) realmode) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE); This OFW operates in what GRUB calls real mode (not to be confused with x86 realmode!), but /options/real-mode? doesn't exist. Should we probe for the actual feature (/chosen/mmu IIRC), probe for firmware version, or #ifdef it for x86 CPUs? This OFW operates in virtual mode, but happens to have an identity mapping of low memory for convenience. -void cmain (uint32_t r3, uint32_t r4, uint32_t r5); void -cmain (UNUSED uint32_t r3, UNUSED uint32_t r4, uint32_t r5) +cmain (void) { - grub_ieee1275_entry_fn = (int (*)(void *)) r5; - This was the only powerpc-specific part of that file, that I can tell. I moved grub_ieee1275_entry_fn initialisation to startup.S. I'd suggest doing the same on powerpc/sparc and move cmain.c out of powerpc/ directory. diff -x '*.mk' -x '*~' -x CVS -x .svn -x configure -x config.h.in -Nurp ../../grub2/kern/powerpc/ieee1275/init.c ./kern/powerpc/ieee1275/init.c --- ../../grub2/kern/powerpc/ieee1275/init.c 2008-01-03 23:43:46.0 +0100 +++ ./kern/powerpc/ieee1275/init.c 2008-01-12 03:26:06.0 +0100 @@ -52,15 +52,6 @@ grub_millisleep (grub_uint32_t ms) grub_millisleep_generic (ms); } -void -grub_exit (void) -{ - /* Trap to Open Firmware. */ - asm (trap); - - for (;;); -} Same here. /* Decode each entry and call `hook'. */ i = 0; - while (i sizeof (available)) + while (i sizeof (available) available[i]) Here we were attempting to claim a region that starts at 0x0 and ends at INT_MAX !! I suppose we just need to check for available property length. Need to look more into this. - address = available[i++]; + address = grub_be_to_cpu32 (available[i++]); if (address_cells == 2) -address = (address 32) | available[i++]; +address = (address 32) | grub_be_to_cpu32 (available[i++]); - size = available[i++]; + size = grub_be_to_cpu32 (available[i++]); if (size_cells == 2) -size = (size 32) | available[i++]; +size = (size 32) | grub_be_to_cpu32 (available[i++]); Integer properties are always in network byte order (thanks Mitch for clarifiing). I wonder if we should byteswap all callers of getprop or just mangle the result in the getprop function instead (the
Re: GRUB on OLPC / XO
On Sat, Jan 12, 2008 at 08:02:03AM -1000, Mitch Bradley wrote: Robert Millan wrote: Some comments on things that need polishing. Some are more addressed at one of the two lists than the others, but feel free to join in either case. (also, if you feel this is off-topic in olpc-devel, feel free to ki^W let me know) btw, Mitch mentioned to me on IRC that the ELF loader on XO has some weird modifications to support Minix. Is this documented somewhere? I was mistaken about Minix - there are no Minix-specific hacks in the ELF loader. The only Minix support is a handler for the Minix filesystem layout, which doesn't affect the ELF loader. The ELF loader has two special cases, which are not documented anywhere except the source code (cpu/x86/pc/olpc/linux.fth : ?memtest-elf-map-in ) : a) It recognizes the memtest86 binary that is embedded in OFW, setting up some special mappings that memtest requires (or at least used to require) b) It recognizes the ELF form of the Linux binary and sets up a mapping from virtual c0xx. to physical 00xx. . Normally this isn't used, because we load the bzImage version of Linux. But OFW can load the ELF portion of the Linux kernel, without the bzImage wrapper. If you do it that way, OFW has access to the ELF symbol table and can thus resolve symbolic names for addresses inside Linux. Ok, thanks for the explanation. It doesn't seem like GRUB would be affected then. On Sat, Jan 12, 2008 at 02:42:30PM +0100, Robert Millan wrote: +void +grub_exit (void) +{ + /* Trap to Open Firmware. */ + /* FIXME. */ + + for (;;); +} We used to run trap insttruction on powerpc. I assume for exitting via trap on i386 we need to generate an interrupt; I'm just not sure which is the right number for it. To exit to OFW, call the exit() client service. I see. Is this one expected to work everywhere including Apple etc? We'd probably be better off ditching the __asm__(trap) altogether. To reboot, call boot() with an empty string as the single IN argument. For this we used reset-all. The standard seems to indicate both are equally fine; is that it? To power off, call interpret() with a cmd string of power-off. We used shut-down for this one. Unfortunately not mentioned in the standard (not sure where it came from). Is there a portable way to do this? /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); - grub_load_modules (); +// grub_load_modules (); This generates an out of bounds exception. GRUB puts modules above _end (0x1000-aligned). Is access to that address allowed by OFW ? The ELF loader will map in anything listed in a program header of type PT_LOAD , according to the vaddr, memsize, and filesize fields. If the module area is covered by such a program header, they should be accessible. Ah, that hints at a known bug in our ELF generator (affecting LinuxBI^W Coreboot). I'll check if the patches for that one help. grub_ieee1275_finddevice (/options, options); rc = grub_ieee1275_get_property (options, real-mode?, realmode, sizeof realmode, 0); - if ((rc = 0) realmode) +// if ((rc = 0) realmode) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE); This OFW operates in what GRUB calls real mode (not to be confused with x86 realmode!), but /options/real-mode? doesn't exist. Should we probe for the actual feature (/chosen/mmu IIRC), probe for firmware version, or #ifdef it for x86 CPUs? This OFW operates in virtual mode, but happens to have an identity mapping of low memory for convenience. /chosen/mmu is set to 0, at least on my (qemu) environment. Should clients interpret this as identity mapping, or is this unintended? Thank you! -- Robert Millan GPLv2 I know my rights; I want my phone call! DRM What use is a phone call, if you are unable to speak? (as seen on /.) ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel
Re: GRUB on OLPC / XO
Robert Millan wrote: We used to run trap insttruction on powerpc. I assume for exitting via trap on i386 we need to generate an interrupt; I'm just not sure which is the right number for it. To exit to OFW, call the exit() client service. I see. Is this one expected to work everywhere including Apple etc? We'd probably be better off ditching the __asm__(trap) altogether. In principle, that should work on Apple, but that would only be true if the client program has left the world set up so that OFW can still work. I no longer keep up with what is happening in the PowerPC world. x86 has no trap instruction. The closest equivalent is int N, but that isn't close enough to be useful, because there is no guarantee that any specific INT handlers are available. I'm not even sure why an unspecific trap works on PowerPC. To reboot, call boot() with an empty string as the single IN argument. For this we used reset-all. The standard seems to indicate both are equally fine; is that it? reset-all is probably better. boot() calls reset-all after setting things up to force a re-execution of boot after OFW comes back up, whereas reset-all just makes the firmware restart with whatever default startup action has been configured. (XO has virtually no firmware configurability - it is intended to just work, nothing to screw up - so the distinction is moot for XO). To power off, call interpret() with a cmd string of power-off. We used shut-down for this one. Unfortunately not mentioned in the standard (not sure where it came from). Is there a portable way to do this? I think shut-down is something that the PowerPC OFW community (or perhaps an individual vendor) came up with after the committee went dormant. The XO OFW has power-off but not shut-down. I don't know of a portable way, other than to try both. /* Load pre-loaded modules and free the space. */ grub_register_exported_symbols (); - grub_load_modules (); +// grub_load_modules (); This generates an out of bounds exception. GRUB puts modules above _end (0x1000-aligned). Is access to that address allowed by OFW ? The ELF loader will map in anything listed in a program header of type PT_LOAD , according to the vaddr, memsize, and filesize fields. If the module area is covered by such a program header, they should be accessible. Ah, that hints at a known bug in our ELF generator (affecting LinuxBI^W Coreboot). I'll check if the patches for that one help. grub_ieee1275_finddevice (/options, options); rc = grub_ieee1275_get_property (options, real-mode?, realmode, sizeof realmode, 0); - if ((rc = 0) realmode) +// if ((rc = 0) realmode) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE); This OFW operates in what GRUB calls real mode (not to be confused with x86 realmode!), but /options/real-mode? doesn't exist. Should we probe for the actual feature (/chosen/mmu IIRC), probe for firmware version, or #ifdef it for x86 CPUs? This OFW operates in virtual mode, but happens to have an identity mapping of low memory for convenience. /chosen/mmu is set to 0, at least on my (qemu) environment. Should clients interpret this as identity mapping, or is this unintended? That is probably a bug in the OFW build. Thank you! ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel
Re: GRUB on OLPC / XO
I was wrong about the mmu thing. I just checked the patch instructions at http://openbios.org/Open_Firmware and noticed that the patch comments out create virtual-mode. So if you build with that patch, you get physical addressing. I don't know what is right, because this build configuration is not for a real product, so the requirements are unclear. ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel
Re: GRUB on OLPC / XO
On Sat, Jan 12, 2008 at 09:44:09AM -1000, Mitch Bradley wrote: I was wrong about the mmu thing. I just checked the patch instructions at http://openbios.org/Open_Firmware and noticed that the patch comments out create virtual-mode. So if you build with that patch, you get physical addressing. I don't know what is right, because this build configuration is not for a real product, so the requirements are unclear. Ok, so for XO it is enabled? -- Robert Millan GPLv2 I know my rights; I want my phone call! DRM What use is a phone call, if you are unable to speak? (as seen on /.) ___ Devel mailing list Devel@lists.laptop.org http://lists.laptop.org/listinfo/devel