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