mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
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:
committed by
Laurent Vivier
parent
3fbece06c9
commit
6a16562087
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user