mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Add bootinfo-loader.
Signed-off-by: Laurent Vivier <Laurent@vivier.eu> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@584 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -229,27 +229,13 @@ try_path(const char *path, const char *param)
|
||||
/* won't come here */
|
||||
}
|
||||
|
||||
/*
|
||||
Parse SGML structure like:
|
||||
<chrp-boot>
|
||||
<description>Debian/GNU Linux Installation on IBM CHRP hardware</description>
|
||||
<os-name>Debian/GNU Linux for PowerPC</os-name>
|
||||
<boot-script>boot &device;:\install\yaboot</boot-script>
|
||||
<icon size=64,64 color-space=3,3,2>
|
||||
|
||||
CHRP system bindings are described at:
|
||||
http://playground.sun.com/1275/bindings/chrp/chrp1_7a.ps
|
||||
*/
|
||||
static void
|
||||
try_chrp_script(const char *of_path, const char *param, const char *script_path)
|
||||
{
|
||||
int tag, taglen, script, scriptlen, entity, chrp;
|
||||
char tagbuf[128], path[1024], c;
|
||||
char path[1024];
|
||||
char *device, *filename, *directory;
|
||||
int partition;
|
||||
int current, size;
|
||||
char *base;
|
||||
char *bootscript;
|
||||
int size;
|
||||
|
||||
device = get_device(of_path);
|
||||
partition = get_partition(of_path);
|
||||
@@ -274,98 +260,7 @@ try_chrp_script(const char *of_path, const char *param, const char *script_path)
|
||||
ELF_DPRINTF("Can't open %s\n", of_path);
|
||||
return;
|
||||
}
|
||||
bootscript = malloc(size);
|
||||
if (bootscript == NULL) {
|
||||
ELF_DPRINTF("Can't malloc %d bytes\n", size);
|
||||
return;
|
||||
}
|
||||
feval("load-base");
|
||||
base = (char*)POP();
|
||||
|
||||
chrp = 0;
|
||||
tag = 0;
|
||||
taglen = 0;
|
||||
script = 0;
|
||||
scriptlen = 0;
|
||||
entity = 0;
|
||||
current = 0;
|
||||
while (current < size) {
|
||||
|
||||
c = base[current++];
|
||||
|
||||
if (c == '<') {
|
||||
script = 0;
|
||||
tag = 1;
|
||||
taglen = 0;
|
||||
} else if (c == '>') {
|
||||
tag = 0;
|
||||
tagbuf[taglen] = '\0';
|
||||
if (strcasecmp(tagbuf, "chrp-boot") == 0) {
|
||||
chrp = 1;
|
||||
} else if (chrp == 1) {
|
||||
if (strcasecmp(tagbuf, "boot-script") == 0) {
|
||||
script = 1;
|
||||
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)) {
|
||||
tagbuf[taglen++] = c;
|
||||
} else if (script && c == '&') {
|
||||
entity = 1;
|
||||
taglen = 0;
|
||||
} else if (entity && c ==';') {
|
||||
entity = 0;
|
||||
tagbuf[taglen] = '\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);
|
||||
scriptlen += strlen(device);
|
||||
} else if (strcasecmp(tagbuf, "partition") == 0) {
|
||||
if (partition != -1)
|
||||
sprintf(bootscript + scriptlen, "%d", partition);
|
||||
else
|
||||
*(bootscript + scriptlen) = 0;
|
||||
scriptlen = strlen(bootscript);
|
||||
} else if (strcasecmp(tagbuf, "directory") == 0) {
|
||||
strcpy(bootscript + scriptlen, directory);
|
||||
scriptlen += strlen(directory);
|
||||
} else if (strcasecmp(tagbuf, "filename") == 0) {
|
||||
strcpy(bootscript + scriptlen, filename);
|
||||
scriptlen += strlen(filename);
|
||||
} else if (strcasecmp(tagbuf, "full-path") == 0) {
|
||||
strcpy(bootscript + scriptlen, of_path);
|
||||
scriptlen += strlen(of_path);
|
||||
} else { /* unknown, keep it */
|
||||
bootscript[scriptlen] = '&';
|
||||
strcpy(bootscript + scriptlen + 1, tagbuf);
|
||||
scriptlen += taglen + 1;
|
||||
bootscript[scriptlen] = ';';
|
||||
scriptlen++;
|
||||
}
|
||||
} else if (entity && taglen < sizeof(tagbuf)) {
|
||||
tagbuf[taglen++] = c;
|
||||
} else if (script && scriptlen < size) {
|
||||
bootscript[scriptlen++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
free(bootscript);
|
||||
feval("go");
|
||||
}
|
||||
|
||||
#define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000)
|
||||
|
||||
@@ -122,7 +122,7 @@ for RULES_ARCH in $*; do
|
||||
;;
|
||||
|
||||
sparc32)
|
||||
TARGET="sparc-elf-"
|
||||
TARGET="sparc-linux-gnu-"
|
||||
CFLAGS="-Wa,-xarch=v8 -Wa,-32 -m32 -mcpu=supersparc -fno-builtin"
|
||||
AS_FLAGS="-Wa,-xarch=v8 -Wa,-32"
|
||||
;;
|
||||
|
||||
@@ -181,6 +181,8 @@ constant /Elf32_Ehdr
|
||||
|
||||
variable elf-entry
|
||||
variable xcoff-entry
|
||||
variable bootinfo-entry
|
||||
variable bootinfo-size
|
||||
|
||||
: init-program-elf
|
||||
elf file-type !
|
||||
@@ -317,7 +319,15 @@ variable xcoff-entry
|
||||
." go is not yet implemented"
|
||||
[THEN]
|
||||
else
|
||||
." go is not yet implemented"
|
||||
bootinfo file-type @ = if
|
||||
[IFDEF] CONFIG_PPC
|
||||
bootinfo-entry @ bootinfo-size @ evaluate
|
||||
[ELSE]
|
||||
." go is not yet implemented"
|
||||
[THEN]
|
||||
else
|
||||
." go is not yet implemented"
|
||||
then
|
||||
then
|
||||
then
|
||||
;
|
||||
|
||||
242
modules/bootinfo-loader.c
Normal file
242
modules/bootinfo-loader.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
*
|
||||
* <bootinfo-loader.c>
|
||||
*
|
||||
* bootinfo file loader
|
||||
*
|
||||
* Copyright (C) 2009 Laurent Vivier (Laurent@vivier.eu)
|
||||
*
|
||||
* Original XML parser by Blue Swirl <blauwirbel@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2
|
||||
*
|
||||
*/
|
||||
|
||||
#include "openbios/config.h"
|
||||
#include "openbios/bindings.h"
|
||||
#include "modules.h"
|
||||
#include "ofmem.h"
|
||||
#include "stdio.h"
|
||||
|
||||
//#define DEBUG_BOOTINFO
|
||||
|
||||
#ifdef DEBUG_BOOTINFO
|
||||
#define DPRINTF(fmt, args...) \
|
||||
do { printk("%s: " fmt, __func__ , ##args); } while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, args...) \
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
DECLARE_NODE(bootinfo_loader, INSTALL_OPEN, 0, "+/packages/bootinfo-loader" );
|
||||
|
||||
static char *
|
||||
get_device( const char *path )
|
||||
{
|
||||
int i;
|
||||
static char buf[1024];
|
||||
|
||||
for (i = 0; i < sizeof(buf) && path[i] && path[i] != ':'; i++)
|
||||
buf[i] = path[i];
|
||||
buf[i] = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int
|
||||
get_partition( const char *path )
|
||||
{
|
||||
while ( *path && *path != ':' )
|
||||
path++;
|
||||
|
||||
if (!*path)
|
||||
return -1;
|
||||
path++;
|
||||
|
||||
if (!strchr(path, ',')) /* check if there is a ',' */
|
||||
return -1;
|
||||
|
||||
return atol(path);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_filename( const char * path , char **dirname)
|
||||
{
|
||||
static char buf[1024];
|
||||
char *filename;
|
||||
|
||||
while ( *path && *path != ':' )
|
||||
path++;
|
||||
|
||||
if (!*path) {
|
||||
*dirname = NULL;
|
||||
return NULL;
|
||||
}
|
||||
path++;
|
||||
|
||||
while ( *path && isdigit(*path) )
|
||||
path++;
|
||||
|
||||
if (*path == ',')
|
||||
path++;
|
||||
|
||||
strncpy(buf, path, sizeof(buf));
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
|
||||
filename = strrchr(buf, '\\');
|
||||
if (filename) {
|
||||
*dirname = buf;
|
||||
(*filename++) = 0;
|
||||
} else {
|
||||
*dirname = NULL;
|
||||
filename = buf;
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
/*
|
||||
Parse SGML structure like:
|
||||
<chrp-boot>
|
||||
<description>Debian/GNU Linux Installation on IBM CHRP hardware</description>
|
||||
<os-name>Debian/GNU Linux for PowerPC</os-name>
|
||||
<boot-script>boot &device;:\install\yaboot</boot-script>
|
||||
<icon size=64,64 color-space=3,3,2>
|
||||
|
||||
CHRP system bindings are described at:
|
||||
http://playground.sun.com/1275/bindings/chrp/chrp1_7a.ps
|
||||
*/
|
||||
|
||||
static void
|
||||
bootinfo_loader_init_program( void *dummy )
|
||||
{
|
||||
char *base;
|
||||
int proplen;
|
||||
phandle_t chosen;
|
||||
int tag, taglen, script, scriptlen, entity, chrp;
|
||||
char tagbuf[128], c;
|
||||
char *device, *filename, *directory;
|
||||
int partition;
|
||||
int current, size;
|
||||
char *bootscript;
|
||||
char *tmp;
|
||||
char bootpath[1024];
|
||||
|
||||
chosen = find_dev("/chosen");
|
||||
tmp = get_property(chosen, "bootpath", &proplen);
|
||||
memcpy(bootpath, tmp, proplen);
|
||||
bootpath[proplen] = 0;
|
||||
|
||||
DPRINTF("bootpath %s\n", bootpath);
|
||||
|
||||
device = get_device(bootpath);
|
||||
partition = get_partition(bootpath);
|
||||
filename = get_filename(bootpath, &directory);
|
||||
|
||||
feval("load-base");
|
||||
base = (char*)POP();
|
||||
|
||||
feval("load-size");
|
||||
size = POP();
|
||||
|
||||
bootscript = malloc(size);
|
||||
if (bootscript == NULL) {
|
||||
DPRINTF("Can't malloc %d bytes\n", size);
|
||||
return;
|
||||
}
|
||||
|
||||
chrp = 0;
|
||||
tag = 0;
|
||||
taglen = 0;
|
||||
script = 0;
|
||||
scriptlen = 0;
|
||||
entity = 0;
|
||||
current = 0;
|
||||
while (current < size) {
|
||||
|
||||
c = base[current++];
|
||||
|
||||
if (c == '<') {
|
||||
script = 0;
|
||||
tag = 1;
|
||||
taglen = 0;
|
||||
} else if (c == '>') {
|
||||
tag = 0;
|
||||
tagbuf[taglen] = '\0';
|
||||
if (strcasecmp(tagbuf, "chrp-boot") == 0) {
|
||||
chrp = 1;
|
||||
} else if (chrp == 1) {
|
||||
if (strcasecmp(tagbuf, "boot-script") == 0) {
|
||||
script = 1;
|
||||
scriptlen = 0;
|
||||
} else if (strcasecmp(tagbuf, "/boot-script") == 0) {
|
||||
|
||||
script = 0;
|
||||
bootscript[scriptlen] = '\0';
|
||||
|
||||
DPRINTF("got bootscript %s\n",
|
||||
bootscript);
|
||||
|
||||
/* FIXME: should initialize saved-program-state. */
|
||||
push_str(bootscript);
|
||||
feval("bootinfo-size ! bootinfo-entry !");
|
||||
|
||||
break;
|
||||
} else if (strcasecmp(tagbuf, "/chrp-boot") == 0)
|
||||
break;
|
||||
}
|
||||
} else if (tag && taglen < sizeof(tagbuf)) {
|
||||
tagbuf[taglen++] = c;
|
||||
} else if (script && c == '&') {
|
||||
entity = 1;
|
||||
taglen = 0;
|
||||
} else if (entity && c ==';') {
|
||||
entity = 0;
|
||||
tagbuf[taglen] = '\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);
|
||||
scriptlen += strlen(device);
|
||||
} else if (strcasecmp(tagbuf, "partition") == 0) {
|
||||
if (partition != -1)
|
||||
sprintf(bootscript + scriptlen, "%d", partition);
|
||||
else
|
||||
*(bootscript + scriptlen) = 0;
|
||||
scriptlen = strlen(bootscript);
|
||||
} else if (strcasecmp(tagbuf, "directory") == 0) {
|
||||
strcpy(bootscript + scriptlen, directory);
|
||||
scriptlen += strlen(directory);
|
||||
} else if (strcasecmp(tagbuf, "filename") == 0) {
|
||||
strcpy(bootscript + scriptlen, filename);
|
||||
scriptlen += strlen(filename);
|
||||
} else if (strcasecmp(tagbuf, "full-path") == 0) {
|
||||
strcpy(bootscript + scriptlen, bootpath);
|
||||
scriptlen += strlen(bootpath);
|
||||
} else { /* unknown, keep it */
|
||||
bootscript[scriptlen] = '&';
|
||||
strcpy(bootscript + scriptlen + 1, tagbuf);
|
||||
scriptlen += taglen + 1;
|
||||
bootscript[scriptlen] = ';';
|
||||
scriptlen++;
|
||||
}
|
||||
} else if (entity && taglen < sizeof(tagbuf)) {
|
||||
tagbuf[taglen++] = c;
|
||||
} else if (script && scriptlen < size) {
|
||||
bootscript[scriptlen++] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NODE_METHODS( bootinfo_loader ) = {
|
||||
{ "init-program", bootinfo_loader_init_program },
|
||||
};
|
||||
|
||||
void bootinfo_loader_init( void )
|
||||
{
|
||||
REGISTER_NODE( bootinfo_loader );
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
<object source="ofmem_common.c" condition="OFMEM"/>
|
||||
<object source="elf-loader.c" condition="PPC"/>
|
||||
<object source="xcoff-loader.c" condition="PPC"/>
|
||||
<object source="bootinfo-loader.c" condition="PPC"/>
|
||||
</library>
|
||||
|
||||
<dictionary name="openbios" target="forth">
|
||||
|
||||
@@ -45,5 +45,6 @@ modules_init( void )
|
||||
#ifdef CONFIG_PPC
|
||||
elf_loader_init();
|
||||
xcoff_loader_init();
|
||||
bootinfo_loader_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -26,5 +26,6 @@ extern void sunparts_init( void );
|
||||
extern void cmdline_init( void );
|
||||
extern void elf_loader_init( void );
|
||||
extern void xcoff_loader_init( void );
|
||||
extern void bootinfo_loader_init( void );
|
||||
|
||||
#endif /* _H_MODULES */
|
||||
|
||||
Reference in New Issue
Block a user