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>



git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@552 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Laurent Vivier
2009-08-12 19:55:31 +00:00
committed by Laurent Vivier
parent 3fbece06c9
commit 6a16562087
4 changed files with 88 additions and 69 deletions

View File

@@ -321,68 +321,45 @@ try_chrp_script(const char *of_path, const char *param, const char *script_path)
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));
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);
/* 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);
call_elf(0, 0, OLDWORLD_BOOTCODE_BASEADDR);
return;
}
@@ -495,7 +472,7 @@ boot( void )
check_preloaded_kernel();
}
if (boot_device == 'c') {
quik_startup();
oldworld_boot();
}
yaboot_startup();
}

View File

@@ -298,7 +298,9 @@ devread( unsigned long sector, unsigned long byte_offset,
}
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;

View File

@@ -57,42 +57,46 @@ dlabel_close( dlabel_info_t *di )
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 @@ dlabel_open( dlabel_info_t *di )
/* 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 @@ dlabel_open( dlabel_info_t *di )
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 @@ dlabel_open( dlabel_info_t *di )
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);

View File

@@ -49,13 +49,25 @@ macparts_open( macparts_info_t *di )
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 @@ macparts_open( macparts_info_t *di )
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 @@ macparts_open( macparts_info_t *di )
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);
}