Use the load method to load and execute CHRP script.

This adds a better support of Apple BootX script.
However, "init-program" and "go" are always missing to be able to really boot with BootX.

Signed-off-by: Laurent Vivier <Laurent@vivier.eu>


git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@576 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Laurent Vivier
2009-09-01 23:44:24 +00:00
parent 95a04cec0e
commit 38283e32ac

View File

@@ -38,6 +38,14 @@
#define ELF_DPRINTF(fmt, args...) SUBSYS_DPRINTF("ELF", fmt, ##args) #define ELF_DPRINTF(fmt, args...) SUBSYS_DPRINTF("ELF", fmt, ##args)
#define NEWWORLD_DPRINTF(fmt, args...) SUBSYS_DPRINTF("NEWWORLD", fmt, ##args) #define NEWWORLD_DPRINTF(fmt, args...) SUBSYS_DPRINTF("NEWWORLD", fmt, ##args)
static void
load(const char *path)
{
char buffer[1024];
sprintf(buffer, "load %s", path);
feval(buffer);
}
static void static void
transfer_control_to_elf( ulong elf_entry ) transfer_control_to_elf( ulong elf_entry )
{ {
@@ -235,10 +243,13 @@ try_path(const char *path, const char *param)
static void static void
try_chrp_script(const char *of_path, const char *param, const char *script_path) try_chrp_script(const char *of_path, const char *param, const char *script_path)
{ {
int fd, len, tag, taglen, script, scriptlen, entity; int tag, taglen, script, scriptlen, entity, chrp;
char tagbuf[256], bootscript[2048], c; char tagbuf[128], path[1024], c;
char *device, *filename, *directory; char *device, *filename, *directory;
int partition; int partition;
int current, size;
char *base;
char *bootscript;
device = get_device(of_path); device = get_device(of_path);
partition = get_partition(of_path); partition = get_partition(of_path);
@@ -249,31 +260,39 @@ try_chrp_script(const char *of_path, const char *param, const char *script_path)
/* read boot script */ /* read boot script */
if (partition == -1) if (partition == -1)
snprintf(bootscript, sizeof(bootscript), "%s:,%s", snprintf(path, sizeof(path), "%s:,%s",
device, script_path); device, script_path);
else else
snprintf(bootscript, sizeof(bootscript), "%s:%d,%s", snprintf(path, sizeof(path), "%s:%d,%s",
device, partition, script_path); device, partition, script_path);
CHRP_DPRINTF("Trying %s\n", bootscript); CHRP_DPRINTF("Trying %s\n", path);
if ((fd = open_io(bootscript)) == -1) { load(path);
ELF_DPRINTF("Can't open %s\n", bootscript); feval("load-size");
size = POP();
if (size == 0) {
ELF_DPRINTF("Can't open %s\n", of_path);
return; return;
} }
len = read_io(fd, tagbuf, 11); bootscript = malloc(size);
tagbuf[11] = '\0'; if (bootscript == NULL) {
if (len < 0 || strcasecmp(tagbuf, "<chrp-boot>") != 0) ELF_DPRINTF("Can't malloc %d bytes\n", size);
goto badf; return;
}
feval("load-base");
base = (char*)POP();
chrp = 0;
tag = 0; tag = 0;
taglen = 0; taglen = 0;
script = 0; script = 0;
scriptlen = 0; scriptlen = 0;
entity = 0; entity = 0;
do { current = 0;
len = read_io(fd, &c, 1); while (current < size) {
if (len < 0)
goto badf; c = base[current++];
if (c == '<') { if (c == '<') {
script = 0; script = 0;
tag = 1; tag = 1;
@@ -281,12 +300,27 @@ try_chrp_script(const char *of_path, const char *param, const char *script_path)
} else if (c == '>') { } else if (c == '>') {
tag = 0; tag = 0;
tagbuf[taglen] = '\0'; tagbuf[taglen] = '\0';
if (strcasecmp(tagbuf, "boot-script") == 0) if (strcasecmp(tagbuf, "chrp-boot") == 0) {
script = 1; chrp = 1;
else if (strcasecmp(tagbuf, "/boot-script") == 0) } else if (chrp == 1) {
bootscript[scriptlen] = '\0'; if (strcasecmp(tagbuf, "boot-script") == 0) {
else if (strcasecmp(tagbuf, "/chrp-boot") == 0) script = 1;
break; scriptlen = 0;
} else if (strcasecmp(tagbuf, "/boot-script") == 0) {
script = 0;
bootscript[scriptlen] = '\0';
CHRP_DPRINTF("got bootscript %s\n", bootscript);
encode_bootpath(of_path, param);
feval(bootscript);
break;
} else if (strcasecmp(tagbuf, "/chrp-boot") == 0)
break;
}
} else if (tag && taglen < sizeof(tagbuf)) { } else if (tag && taglen < sizeof(tagbuf)) {
tagbuf[taglen++] = c; tagbuf[taglen++] = c;
} else if (script && c == '&') { } else if (script && c == '&') {
@@ -295,7 +329,11 @@ try_chrp_script(const char *of_path, const char *param, const char *script_path)
} else if (entity && c ==';') { } else if (entity && c ==';') {
entity = 0; entity = 0;
tagbuf[taglen] = '\0'; tagbuf[taglen] = '\0';
if (strcasecmp(tagbuf, "device") == 0) { if (strcasecmp(tagbuf, "lt") == 0) {
bootscript[scriptlen++] = '<';
} else if (strcasecmp(tagbuf, "gt") == 0) {
bootscript[scriptlen++] = '>';
} else if (strcasecmp(tagbuf, "device") == 0) {
strcpy(bootscript + scriptlen, device); strcpy(bootscript + scriptlen, device);
scriptlen += strlen(device); scriptlen += strlen(device);
} else if (strcasecmp(tagbuf, "partition") == 0) { } else if (strcasecmp(tagbuf, "partition") == 0) {
@@ -322,18 +360,12 @@ try_chrp_script(const char *of_path, const char *param, const char *script_path)
} }
} else if (entity && taglen < sizeof(tagbuf)) { } else if (entity && taglen < sizeof(tagbuf)) {
tagbuf[taglen++] = c; tagbuf[taglen++] = c;
} else if (script && scriptlen < sizeof(bootscript)) { } else if (script && scriptlen < size) {
bootscript[scriptlen++] = c; bootscript[scriptlen++] = c;
} }
} while (1); }
CHRP_DPRINTF("got bootscript %s\n", bootscript); free(bootscript);
encode_bootpath(of_path, param);
feval(bootscript);
badf:
close_io( fd );
} }
#define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000) #define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000)