Hi,
the attached patch allows to boot using "boot hd:%BOOT". This is the method used by OldWorld bootloader, Quik.
As I've only tested it with PPC target, I'd like to have some comments before commiting it (If someone can test sparc, I'll be happy).
Regards, Laurent
On 11.08.2009, at 23:13, Laurent Vivier Laurent@vivier.eu wrote:
Hi,
the attached patch allows to boot using "boot hd:%BOOT". This is the method used by OldWorld bootloader, Quik.
As I've only tested it with PPC target, I'd like to have some comments before commiting it (If someone can test sparc, I'll be happy).
Since it is part of PPC only CHRP, I think it should be fine to make sure the code is only used on PPC, I believe...
Stefan
Regards, Laurent This patch allows to boot from bootsector of first bootable partition using "boot hd:%BOOT" As explained in: "PowerPC Microprocessor Common Hardware Reference Platform (CHRP) System binding to: IEEE Std 1275-1994 Standard for Boot (Initialization, Configuration) Firmware Revision: 1.8" "Chapter 11.1.2. Open Method Algorith" Signed-off-by: Laurent Vivier --- arch/ppc/qemu/main.c | 63 +++++++++++-------------------------- fs/grubfs/grubfs_fs.c | 2 + modules/disk-label.c | 84 ++++++++++++++++++++++++++++ +--------------------- modules/mac-parts.c | 23 ++++++++++++- 4 files changed, 92 insertions(+), 80 deletions(-) Index: openbios- devel/modules/disk-label.c =================================================================== --- openbios-devel.orig/modules/disk-label.c 2009-08-11 22:20:03.000000000 +0200 +++ openbios-devel/modules/disk-label.c 2009-08-11 22:47:59.000000000 +0200 @@ -57,42 +57,28 @@ static void dlabel_open( dlabel_info_t *di ) { - char *s, *filename, *parstr; + char *path; char block0 [512]; phandle_t ph; int fd, success=0; xt_t xt; - parstr = my_args_copy(); - DPRINTF("dlabel-open '%s'\n", parstr ); + path = my_args_copy(); + DPRINTF("dlabel-open '%s'\n", path ); + + /* open disk interface */ if( (fd=open_ih(my_parent())) == -1 ) goto out; di-
fd = fd; - /* argument format: parnum,filename */ - s = parstr; -
filename = NULL; - if( s ) { - if( *s == '-' || isdigit(*s) || - (*s
= 'a' && *s < ('a' + 8) - && (*(s + 1) == ',' || *(s + 1) ==
'\0'))) { - if( (s=strpbrk(parstr,",")) ) { - filename = s+1; - *s = 0; - } - } else { - filename = s; - parstr = NULL; - if ( *s == ',' ) - filename++; - } - } - DPRINTF("parstr %s filename %s \n", parstr, filename); - - /* try to see if there is a filesystem without partition */ + /* try to see if there is a filesystem without partition, + * like ISO9660. This is needed to boot openSUSE 11.1 CD + * which uses "boot &device;:1,\suseboot \yaboot.ibm" + * whereas HFS+ partition is #2 + */ - if (atol (parstr) == 1) { + if ( atol(path) == 1 ) { PUSH_ih( my_self() ); selfword("find-filesystem"); ph = POP_ph(); @@ -109,11 +95,7 @@ call_parent(xt); di->block_size = POP(); } - push_str( filename );
- PUSH_ph( ph ); - fword("interpose"); - success = 1; - goto out;
goto open_file; } } @@ -127,7 +109,7 @@ /* open partition
package */ if( ph ) { - if( !(di->part_ih=open_package(parstr, ph)) ) + if( !(di->part_ih=open_package(path, ph)) ) goto out; if( ! (xt=find_ih_method("get-info", di->part_ih)) ) goto out; @@ -143,24 +125,56 @@ call_package(xt, di->part_ih); di->block_size = POP(); }
- } else { + /* unknown (or missing) partition map, + * try the
whole disk + */ + di->offs_hi = 0; + di->offs_lo = 0; + di-
size_hi = 0; + di->size_lo = 0; + di->part_ih = 0; + di->type =
-1; + di->block_size = 512; + xt = find_parent_method("block- size"); + if (xt) { + call_parent(xt); + di->block_size = POP();
} } /* probe for filesystem */ + PUSH_ih( my_self() ); selfword
("find-filesystem"); ph = POP_ph(); if( ph ) { + char *s, *filename; +open_file: + /* argument format: parnum,filename */ + s = path; + filename = NULL; + if( *s == '-' || isdigit(*s) || + (*s >= 'a' && *s < ('a' + 8) + && (*(s + 1) == ',' || *(s + 1) == '\0'))) { + if( (s=strpbrk(path,",")) ) { + filename = s+1; + }
} else { + filename = s; + if( *s == ',' ) + filename++; + } +
DPRINTF("filename %s\n", filename); push_str( filename ); PUSH_ph ( ph ); fword("interpose"); - } else if( filename ) { - goto out; } success = 1; out: - if( parstr ) - free( parstr ); + if( path ) + free( path ); if( !success ) { dlabel_close( di ); RET(0); Index: openbios-devel/modules/mac-parts.c =================================================================== --- openbios-devel.orig/modules/mac-parts.c 2009-08-11 22:20:03.000000000 +0200 +++ openbios-devel/modules/mac-parts.c 2009-08-11 22:47:59.000000000 +0200 @@ -49,13 +49,25 @@ desc_map_t dmap; part_entry_t par; int ret = 0; + int want_bootcode = 0; + DPRINTF("partition %s\n", str); if( str ) { + char *tmp; parnum = atol(str); if( *str == 0 || *str == ',' ) parnum = -1; + tmp = str; + while (*tmp && *tmp != ',')
tmp++; + if (*tmp == ',') + tmp++; + if (strcmp(tmp, "%BOOT")
== 0) + want_bootcode = 1; + free(str); } + DPRINTF("want_bootcode %d\n", want_bootcode); DPRINTF("macparts_open %d\n", parnum); SEEK ( 0 ); if( READ(&dmap, sizeof(dmap)) != sizeof(dmap) ) @@ -97,6 +109,10 @@ di->blocksize =(uint)bs; di->offs = (llong) par.pmPyPartStart * bs; di->size = (llong)par.pmPartBlkCnt * bs; + if (want_bootcode) { + di->offs += (llong)par.pmLgBootStart*bs; + di->size = (llong)par.pmBootSize; + } ret = -1; goto out; } @@ -132,10 +148,13 @@ di->blocksize =(uint)bs; di->offs = (llong) par.pmPyPartStart * bs; di->size = (llong)par.pmPartBlkCnt * bs; + if (want_bootcode) { + di->offs += (llong)par.pmLgBootStart * bs;
di->size = (llong)par.pmBootSize; + } out: - if (str) - free
(str); + DPRINTF("offset 0x%llx size 0x%llx\n", di->offs, di->size); PUSH( ret); } Index: openbios-devel/arch/ppc/qemu/main.c =================================================================== --- openbios-devel.orig/arch/ppc/qemu/main.c 2009-08-11 22:20:03.000000000 +0200 +++ openbios-devel/arch/ppc/qemu/main.c 2009-08-11 22:58:31.000000000 +0200 @@ -321,68 +321,45 @@ close_io( fd ); } -#define QUIK_SECOND_BASEADDR 0x3e0000 -#define QUIK_FIRST_BASEADDR 0x3f4000 - #define QUIK_SECOND_SIZE (QUIK_FIRST_BASEADDR - QUIK_SECOND_BASEADDR) -#define QUIK_FIRST_INFO_OFF 0x2c8 - -struct first_info { - char quik_vers[8]; - int nblocks; - int blocksize; - unsigned second_base; - int conf_part; - char conf_file[32]; - unsigned blknos[64]; -}; +#define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000) static void -quik_startup( void ) +oldworld_boot( void ) { int fd; - int len; - const char *path = "hd:2"; - union { - char buffer[1024]; - int first_word; - struct { - char pad [QUIK_FIRST_INFO_OFF]; - struct first_info fi; - } fi; - } u; + int len, total; + const char *path = "hd:,%BOOT"; + char *bootcode; if ((fd = open_io(path)) == -1) { ELF_DPRINTF("Can't open %s\n", path); return; } - seek_io(fd, 0); - len = read_io(fd, u.buffer, sizeof(u)); - close_io( fd ); - if (len == -1) { - ELF_DPRINTF ("Can't read %s\n", path); - return; + total = 0; + bootcode = (char*)OLDWORLD_BOOTCODE_BASEADDR; + while(1) { + if (seek_io(fd, total) == -1) + break; + len = read_io(fd, bootcode, 512); + bootcode += len; + total += len; } - /* is it quik ? */ + close_io ( fd ); - if (memcmp(u.fi.fi.quik_vers, "QUIK", 4)) + if (total == -1) { + ELF_DPRINTF("Can't read %s\n", path); return; + } encode_bootpath(path, "Linux"); - if( ofmem_claim ( QUIK_FIRST_BASEADDR, len, 0 ) == -1 ) - fatal_error("Claim failed! \n"); - - memcpy((char*)QUIK_FIRST_BASEADDR, u.buffer, len); - - /* quik fist level doesn't claim second level memory */ - - if ( ofmem_claim( QUIK_SECOND_BASEADDR, QUIK_SECOND_SIZE, 0 ) == -1 ) + if( ofmem_claim( OLDWORLD_BOOTCODE_BASEADDR, total, 0 ) == -1 ) fatal_error("Claim failed!\n"); - call_elf(0, 0, QUIK_FIRST_BASEADDR); + call_elf(0, 0, OLDWORLD_BOOTCODE_BASEADDR); return; } @@ -495,7 +472,7 @@ check_preloaded_kernel(); } if (boot_device == 'c') { - quik_startup(); + oldworld_boot(); } yaboot_startup(); } Index: openbios-devel/fs/grubfs/grubfs_fs.c =================================================================== --- openbios-devel.orig/fs/grubfs/grubfs_fs.c 2009-08-11 22:59:35.000000000 +0200 +++ openbios-devel/fs/grubfs/grubfs_fs.c 2009-08-11 22:59:43.000000000 +0200 @@ -298,7 +298,9 @@ } if( seek_io(curfs->dev_fd, offs) ) { +#ifdef CONFIG_DEBUG_FS printk("seek failure\n"); +#endif return -1; } return (read_io(curfs->dev_fd, buf, byte_len) == byte_len) ? 1:0; -- OpenBIOS http://openbios.org/ Mailinglist: http://lists.openbios.org/mailman/listinfo Free your System - May the Forth be with you
On Tue, Aug 11, 2009 at 11:13:00PM +0200, Laurent Vivier wrote:
the attached patch allows to boot using "boot hd:%BOOT". This is the method used by OldWorld bootloader, Quik.
As I've only tested it with PPC target, I'd like to have some comments before commiting it (If someone can test sparc, I'll be happy).
Regards, Laurent
Excellent. I never could figure out how to fix this to elliminate the ugly hack that was the QUIK support before. I had to do nasty things to maintain compatiblity with the hack when I modified the quik bootloader a few months ago. Now I could get rid of those hacks and make the code nice and clean again.
So this I assume will make the oldworld mac emulation boot QUIK the proper way rather than by being hardcoded to look for the QUIK boot sector at a certain offset. I should give it a try.