Author: laurent Date: 2009-08-12 21:55:31 +0200 (Wed, 12 Aug 2009) New Revision: 552
Modified: trunk/openbios-devel/arch/ppc/qemu/main.c trunk/openbios-devel/fs/grubfs/grubfs_fs.c trunk/openbios-devel/modules/disk-label.c trunk/openbios-devel/modules/mac-parts.c Log: 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 Laurent@vivier.info
Modified: trunk/openbios-devel/arch/ppc/qemu/main.c =================================================================== --- trunk/openbios-devel/arch/ppc/qemu/main.c 2009-08-12 17:29:51 UTC (rev 551) +++ trunk/openbios-devel/arch/ppc/qemu/main.c 2009-08-12 19:55:31 UTC (rev 552) @@ -321,69 +321,46 @@ 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 +#define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000)
-struct first_info { - char quik_vers[8]; - int nblocks; - int blocksize; - unsigned second_base; - int conf_part; - char conf_file[32]; - unsigned blknos[64]; -}; - 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)); + + 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; + } + close_io( fd );
- if (len == -1) { + if (total == 0) { ELF_DPRINTF("Can't read %s\n", path); return; }
- /* is it quik ? */ - - if (memcmp(u.fi.fi.quik_vers, "QUIK", 4)) - return; - encode_bootpath(path, "Linux");
- if( ofmem_claim( QUIK_FIRST_BASEADDR, len, 0 ) == -1 ) + if( ofmem_claim( OLDWORLD_BOOTCODE_BASEADDR, total, 0 ) == -1 ) fatal_error("Claim failed!\n");
- memcpy((char*)QUIK_FIRST_BASEADDR, u.buffer, len); + call_elf(0, 0, OLDWORLD_BOOTCODE_BASEADDR);
- /* quik fist level doesn't claim second level memory */ - - if( ofmem_claim( QUIK_SECOND_BASEADDR, QUIK_SECOND_SIZE, 0 ) == -1 ) - fatal_error("Claim failed!\n"); - - call_elf(0, 0, QUIK_FIRST_BASEADDR); - return; }
@@ -495,7 +472,7 @@ check_preloaded_kernel(); } if (boot_device == 'c') { - quik_startup(); + oldworld_boot(); } yaboot_startup(); }
Modified: trunk/openbios-devel/fs/grubfs/grubfs_fs.c =================================================================== --- trunk/openbios-devel/fs/grubfs/grubfs_fs.c 2009-08-12 17:29:51 UTC (rev 551) +++ trunk/openbios-devel/fs/grubfs/grubfs_fs.c 2009-08-12 19:55:31 UTC (rev 552) @@ -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;
Modified: trunk/openbios-devel/modules/disk-label.c =================================================================== --- trunk/openbios-devel/modules/disk-label.c 2009-08-12 17:29:51 UTC (rev 551) +++ trunk/openbios-devel/modules/disk-label.c 2009-08-12 19:55:31 UTC (rev 552) @@ -57,42 +57,46 @@ static void dlabel_open( dlabel_info_t *di ) { - char *s, *filename, *parstr; + char *s, *filename; + 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; + + s = path; 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++; + 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("parstr %s filename %s\n", parstr, filename); + DPRINTF("filename %s\n", 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(); @@ -127,7 +131,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,9 +147,26 @@ 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(); @@ -153,14 +174,14 @@ push_str( filename ); PUSH_ph( ph ); fword("interpose"); - } else if( filename ) { + } else if (filename && strcmp(filename, "%BOOT") != 0) { goto out; } success = 1;
out: - if( parstr ) - free( parstr ); + if( path ) + free( path ); if( !success ) { dlabel_close( di ); RET(0);
Modified: trunk/openbios-devel/modules/mac-parts.c =================================================================== --- trunk/openbios-devel/modules/mac-parts.c 2009-08-12 17:29:51 UTC (rev 551) +++ trunk/openbios-devel/modules/mac-parts.c 2009-08-12 19:55:31 UTC (rev 552) @@ -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); }