Commit yaboot 1.3.4.
git-archimport-id: erbenson@alaska.net--public/yaboot--devel--1.3--patch-8
# tag: automatic-ChangeLog--erbenson@alaska.net--public/yaboot--devel--1.3
#
+2002-03-26 15:05:27 GMT Ethan Benson <erbenson@alaska.net> patch-8
+
+ Summary:
+ Commit yaboot 1.3.4
+ Revision:
+ yaboot--devel--1.3--patch-8
+
+ Commit yaboot 1.3.4.
+
+ modified files:
+ ChangeLog Makefile changelog include/bootinfo.h
+ include/ctype.h include/debug.h include/file.h second/cfg.c
+ second/file.c second/fs.c second/fs_ext2.c second/fs_iso.c
+ second/iso_util.c second/partition.c second/prom.c
+ second/yaboot.c util/addnote.c ybin/ybin
+
+
2002-03-26 15:00:49 GMT Ethan Benson <erbenson@alaska.net> patch-7
Summary:
include Config
-VERSION = 1.3.4pre3
+VERSION = 1.3.4
# Debug mode (spam/verbose)
DEBUG = 0
# make install vars
-2001-10-12 Ethan Benson <erbenson@alaska.net>
+2001-10-13 Ethan Benson <erbenson@alaska.net>
- * Version 1.3.4pre3
+ * Version 1.3.4
* ybin: Correct a verbosity message.
- * yaboot:
- - Add non-fatal warning when bootstrap partition has wrong type (pmac only).
- - Minor code rearrangment.
-
-2001-10-10 Ethan Benson <erbenson@alaska.net>
-
- * Version 1.3.4pre2
-
- * yaboot:
- - Fix netboot when using the `n' key.
- - Make configuration file open error consistent with other file
- open errors.
-
-2001-10-09 Ethan Benson <erbenson@alaska.net>
-
- * Version 1.3.4pre1
-
* yaboot:
- Add SGI XFS filesystem support.
- Rewrite OpenFirmware device path parsing code. This fixes
many bugs and inconsistencies in yaboot's file loading.
- Fix OpenFirmware filesystem support to automatically convert
path separator from / to \. CDROM authors no longer need to use
- hacks like image=\\install\\powermac\\vmlinux.
+ kludges like image=\\install\\powermac\\vmlinux.
- Fix kernel loading on some systems.
- Allow for getting files from tftp server that does not run a
bootpd/dhcpd.
+ - Fix netboot when using the `n' key.
- Fix a great deal of incorrect format strings which could cause
yaboot crashes.
- Fix all filesystems to properly return error conditions, and
report those error conditions (instead of just saying `image not
found').
+ - Make configuration file open error consistent with other file
+ open errors.
- Add `help' command to yaboot which prints out basic usage information.
+ - Add non-fatal warning when bootstrap partition has wrong type (pmac only).
+ - Minor code rearrangement.
- General cruft removal and code cleanup.
* Makefile cleanup, make filesystems configurable.
#define _MACH_walnut 0x00001000 /* IBM "Walnut" 405GP eval. board */
struct bi_record {
- unsigned long tag; /* tag ID */
- unsigned long size; /* size of record (in bytes) */
- unsigned long data[0]; /* data */
+ unsigned long tag; /* tag ID */
+ unsigned long size; /* size of record (in bytes) */
+ unsigned long data[0]; /* data */
};
#define BI_FIRST 0x1010 /* first record - marker */
#endif /* _PPC_BOOTINFO_H */
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
static inline unsigned char __tolower(unsigned char c)
{
- if (isupper(c))
- c -= 'A'-'a';
- return c;
+ if (isupper(c))
+ c -= 'A'-'a';
+ return c;
}
static inline unsigned char __toupper(unsigned char c)
{
- if (islower(c))
- c -= 'a'-'A';
- return c;
+ if (islower(c))
+ c -= 'a'-'A';
+ return c;
}
#define tolower(c) __tolower(c)
#define toupper(c) __toupper(c)
#endif
+
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
#define DEBUG_OPEN
#define DEBUG_SLEEP
#endif
+
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
parse_device_path(char *imagepath, char *defdevice, int defpart,
char *deffile, struct boot_fspec_t *result);
-#if 0
-extern int validate_fspec(
- struct boot_fspec_t* spec,
- char* default_device,
- int default_part);
-extern char *parse_device_path(
- char* of_device,
- char** file_spec,
- int* partition);
-#endif
-
#endif
extern int strcasecmp(const char *s1, const char *s2);
typedef enum {
- cft_strg, cft_flag, cft_end
+ cft_strg, cft_flag, cft_end
} CONFIG_TYPE;
typedef struct {
- CONFIG_TYPE type;
- char *name;
- void *data;
+ CONFIG_TYPE type;
+ char *name;
+ void *data;
} CONFIG;
#define MAX_TOKEN 200
CONFIG cf_options[] =
{
- {cft_strg, "device", NULL},
- {cft_strg, "partition", NULL},
- {cft_strg, "default", NULL},
- {cft_strg, "timeout", NULL},
- {cft_strg, "password", NULL},
- {cft_flag, "restricted", NULL},
- {cft_strg, "message", NULL},
- {cft_strg, "root", NULL},
- {cft_strg, "ramdisk", NULL},
- {cft_flag, "read-only", NULL},
- {cft_flag, "read-write", NULL},
- {cft_strg, "append", NULL},
- {cft_strg, "initrd", NULL},
- {cft_flag, "initrd-prompt", NULL},
- {cft_strg, "initrd-size", NULL},
- {cft_flag, "pause-after", NULL},
- {cft_strg, "pause-message", NULL},
- {cft_strg, "init-code", NULL},
- {cft_strg, "init-message", NULL},
- {cft_strg, "fgcolor", NULL},
- {cft_strg, "bgcolor", NULL},
- {cft_strg, "ptypewarning", NULL},
- {cft_end, NULL, NULL}};
+ {cft_strg, "device", NULL},
+ {cft_strg, "partition", NULL},
+ {cft_strg, "default", NULL},
+ {cft_strg, "timeout", NULL},
+ {cft_strg, "password", NULL},
+ {cft_flag, "restricted", NULL},
+ {cft_strg, "message", NULL},
+ {cft_strg, "root", NULL},
+ {cft_strg, "ramdisk", NULL},
+ {cft_flag, "read-only", NULL},
+ {cft_flag, "read-write", NULL},
+ {cft_strg, "append", NULL},
+ {cft_strg, "initrd", NULL},
+ {cft_flag, "initrd-prompt", NULL},
+ {cft_strg, "initrd-size", NULL},
+ {cft_flag, "pause-after", NULL},
+ {cft_strg, "pause-message", NULL},
+ {cft_strg, "init-code", NULL},
+ {cft_strg, "init-message", NULL},
+ {cft_strg, "fgcolor", NULL},
+ {cft_strg, "bgcolor", NULL},
+ {cft_strg, "ptypewarning", NULL},
+ {cft_end, NULL, NULL}};
CONFIG cf_image[] =
{
- {cft_strg, "image", NULL},
- {cft_strg, "label", NULL},
- {cft_strg, "alias", NULL},
- {cft_flag, "single-key", NULL},
- {cft_flag, "restricted", NULL},
- {cft_strg, "device", NULL},
- {cft_strg, "partition", NULL},
- {cft_strg, "root", NULL},
- {cft_strg, "ramdisk", NULL},
- {cft_flag, "read-only", NULL},
- {cft_flag, "read-write", NULL},
- {cft_strg, "append", NULL},
- {cft_strg, "literal", NULL},
- {cft_strg, "initrd", NULL},
- {cft_flag, "initrd-prompt", NULL},
- {cft_strg, "initrd-size", NULL},
- {cft_flag, "pause-after", NULL},
- {cft_strg, "pause-message", NULL},
- {cft_flag, "novideo", NULL},
- {cft_strg, "sysmap", NULL},
- {cft_end, NULL, NULL}};
+ {cft_strg, "image", NULL},
+ {cft_strg, "label", NULL},
+ {cft_strg, "alias", NULL},
+ {cft_flag, "single-key", NULL},
+ {cft_flag, "restricted", NULL},
+ {cft_strg, "device", NULL},
+ {cft_strg, "partition", NULL},
+ {cft_strg, "root", NULL},
+ {cft_strg, "ramdisk", NULL},
+ {cft_flag, "read-only", NULL},
+ {cft_flag, "read-write", NULL},
+ {cft_strg, "append", NULL},
+ {cft_strg, "literal", NULL},
+ {cft_strg, "initrd", NULL},
+ {cft_flag, "initrd-prompt", NULL},
+ {cft_strg, "initrd-size", NULL},
+ {cft_flag, "pause-after", NULL},
+ {cft_strg, "pause-message", NULL},
+ {cft_flag, "novideo", NULL},
+ {cft_strg, "sysmap", NULL},
+ {cft_end, NULL, NULL}};
static char flag_set;
static char *last_token = NULL, *last_item = NULL, *last_value = NULL;
static jmp_buf env;
static struct IMAGES {
- CONFIG table[sizeof (cf_image) / sizeof (cf_image[0])];
- struct IMAGES *next;
+ CONFIG table[sizeof (cf_image) / sizeof (cf_image[0])];
+ struct IMAGES *next;
} *images = NULL;
void cfg_error (char *msg,...)
{
- va_list ap;
-
- va_start (ap, msg);
- prom_printf ("Config file error: ");
- prom_vprintf (msg, ap);
- va_end (ap);
- prom_printf (" near line %d in file %s\n", line_num, file_name);
- longjmp (env, 1);
+ va_list ap;
+
+ va_start (ap, msg);
+ prom_printf ("Config file error: ");
+ prom_vprintf (msg, ap);
+ va_end (ap);
+ prom_printf (" near line %d in file %s\n", line_num, file_name);
+ longjmp (env, 1);
}
void cfg_warn (char *msg,...)
{
- va_list ap;
+ va_list ap;
- va_start (ap, msg);
- prom_printf ("Config file warning: ");
- prom_vprintf (msg, ap);
- va_end (ap);
- prom_printf (" near line %d in file %s\n", line_num, file_name);
+ va_start (ap, msg);
+ prom_printf ("Config file warning: ");
+ prom_vprintf (msg, ap);
+ va_end (ap);
+ prom_printf (" near line %d in file %s\n", line_num, file_name);
}
inline int getc ()
{
- if (currp == endp)
- return EOF;
- return *currp++;
+ if (currp == endp)
+ return EOF;
+ return *currp++;
}
#define next_raw next
static int next (void)
{
- int ch;
+ int ch;
- if (!back)
- return getc ();
- ch = back;
- back = 0;
- return ch;
+ if (!back)
+ return getc ();
+ ch = back;
+ back = 0;
+ return ch;
}
static void again (int ch)
{
- back = ch;
+ back = ch;
}
static char *cfg_get_token (void)
{
- char buf[MAX_TOKEN + 1];
- char *here;
- int ch, escaped;
-
- if (last_token) {
- here = last_token;
- last_token = NULL;
- return here;
- }
- while (1) {
- while (ch = next (), ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
- if (ch == '\n' || ch == '\r')
- line_num++;
- if (ch == EOF || ch == (int)NULL)
- return NULL;
- if (ch != '#')
- break;
- while (ch = next_raw (), (ch != '\n' && ch != '\r'))
- if (ch == EOF)
- return NULL;
- line_num++;
- }
- if (ch == '=')
- return strdup ("=");
- if (ch == '"') {
- here = buf;
- while (here - buf < MAX_TOKEN) {
- if ((ch = next ()) == EOF)
- cfg_error ("EOF in quoted string");
- if (ch == '"') {
- *here = 0;
- return strdup (buf);
- }
- if (ch == '\\') {
- ch = next ();
- switch (ch) {
- case '"':
- case '\\':
- break;
- case '\n':
- case '\r':
- while ((ch = next ()), ch == ' ' || ch == '\t');
- if (!ch)
- continue;
+ char buf[MAX_TOKEN + 1];
+ char *here;
+ int ch, escaped;
+
+ if (last_token) {
+ here = last_token;
+ last_token = NULL;
+ return here;
+ }
+ while (1) {
+ while (ch = next (), ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
+ if (ch == '\n' || ch == '\r')
+ line_num++;
+ if (ch == EOF || ch == (int)NULL)
+ return NULL;
+ if (ch != '#')
+ break;
+ while (ch = next_raw (), (ch != '\n' && ch != '\r'))
+ if (ch == EOF)
+ return NULL;
+ line_num++;
+ }
+ if (ch == '=')
+ return strdup ("=");
+ if (ch == '"') {
+ here = buf;
+ while (here - buf < MAX_TOKEN) {
+ if ((ch = next ()) == EOF)
+ cfg_error ("EOF in quoted string");
+ if (ch == '"') {
+ *here = 0;
+ return strdup (buf);
+ }
+ if (ch == '\\') {
+ ch = next ();
+ switch (ch) {
+ case '"':
+ case '\\':
+ break;
+ case '\n':
+ case '\r':
+ while ((ch = next ()), ch == ' ' || ch == '\t');
+ if (!ch)
+ continue;
+ again (ch);
+ ch = ' ';
+ break;
+ case 'n':
+ ch = '\n';
+ break;
+ default:
+ cfg_error ("Bad use of \\ in quoted string");
+ }
+ } else if ((ch == '\n') || (ch == '\r'))
+ cfg_error ("newline is not allowed in quoted strings");
+ *here++ = ch;
+ }
+ cfg_error ("Quoted string is too long");
+ return 0; /* not reached */
+ }
+ here = buf;
+ escaped = 0;
+ while (here - buf < MAX_TOKEN) {
+ if (escaped) {
+ if (ch == EOF)
+ cfg_error ("\\ precedes EOF");
+ if (ch == '\n')
+ line_num++;
+ else
+ *here++ = ch == '\t' ? ' ' : ch;
+ escaped = 0;
+ } else {
+ if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '#' ||
+ ch == '=' || ch == EOF) {
again (ch);
- ch = ' ';
- break;
- case 'n':
- ch = '\n';
- break;
- default:
- cfg_error ("Bad use of \\ in quoted string");
- }
- } else if ((ch == '\n') || (ch == '\r'))
- cfg_error ("newline is not allowed in quoted strings");
- *here++ = ch;
- }
- cfg_error ("Quoted string is too long");
- return 0; /* not reached */
- }
- here = buf;
- escaped = 0;
- while (here - buf < MAX_TOKEN) {
- if (escaped) {
- if (ch == EOF)
- cfg_error ("\\ precedes EOF");
- if (ch == '\n')
- line_num++;
- else
- *here++ = ch == '\t' ? ' ' : ch;
- escaped = 0;
- } else {
- if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '#' ||
- ch == '=' || ch == EOF) {
- again (ch);
- *here = 0;
- return strdup (buf);
- }
- if (!(escaped = (ch == '\\')))
- *here++ = ch;
- }
- ch = next ();
- }
- cfg_error ("Token is too long");
- return 0; /* not reached */
+ *here = 0;
+ return strdup (buf);
+ }
+ if (!(escaped = (ch == '\\')))
+ *here++ = ch;
+ }
+ ch = next ();
+ }
+ cfg_error ("Token is too long");
+ return 0; /* not reached */
}
static void cfg_return_token (char *token)
{
- last_token = token;
+ last_token = token;
}
static int cfg_next (char **item, char **value)
{
- char *this;
-
- if (last_item) {
- *item = last_item;
- *value = last_value;
- last_item = NULL;
- return 1;
- }
- *value = NULL;
- if (!(*item = cfg_get_token ()))
- return 0;
- if (!strcmp (*item, "="))
- cfg_error ("Syntax error");
- if (!(this = cfg_get_token ()))
- return 1;
- if (strcmp (this, "=")) {
- cfg_return_token (this);
- return 1;
- }
- if (!(*value = cfg_get_token ()))
- cfg_error ("Value expected at EOF");
- if (!strcmp (*value, "="))
- cfg_error ("Syntax error after %s", *item);
- return 1;
+ char *this;
+
+ if (last_item) {
+ *item = last_item;
+ *value = last_value;
+ last_item = NULL;
+ return 1;
+ }
+ *value = NULL;
+ if (!(*item = cfg_get_token ()))
+ return 0;
+ if (!strcmp (*item, "="))
+ cfg_error ("Syntax error");
+ if (!(this = cfg_get_token ()))
+ return 1;
+ if (strcmp (this, "=")) {
+ cfg_return_token (this);
+ return 1;
+ }
+ if (!(*value = cfg_get_token ()))
+ cfg_error ("Value expected at EOF");
+ if (!strcmp (*value, "="))
+ cfg_error ("Syntax error after %s", *item);
+ return 1;
}
#if 0
// below, so we don't need this unless we decide to use it again.
static void cfg_return (char *item, char *value)
{
- last_item = item;
- last_value = value;
+ last_item = item;
+ last_value = value;
}
#endif
static int cfg_set (char *item, char *value)
{
- CONFIG *walk;
-
- if (!strcasecmp (item, "image")) {
- struct IMAGES **p = &images;
-
- while (*p)
- p = &((*p)->next);
- *p = (struct IMAGES *)malloc (sizeof (struct IMAGES));
- if (*p == NULL) {
- prom_printf("malloc error in cfg_set\n");
- return -1;
- }
- (*p)->next = 0;
- curr_table = ((*p)->table);
- memcpy (curr_table, cf_image, sizeof (cf_image));
- }
- for (walk = curr_table; walk->type != cft_end; walk++) {
- if (walk->name && !strcasecmp (walk->name, item)) {
- if (value && walk->type != cft_strg)
- cfg_warn ("'%s' doesn't have a value", walk->name);
- else if (!value && walk->type == cft_strg)
- cfg_warn ("Value expected for '%s'", walk->name);
- else {
- if (walk->data)
- cfg_warn ("Duplicate entry '%s'", walk->name);
- if (walk->type == cft_flag)
- walk->data = &flag_set;
- else if (walk->type == cft_strg)
- walk->data = value;
- }
- break;
- }
- }
- if (walk->type != cft_end)
- return 1;
+ CONFIG *walk;
+
+ if (!strcasecmp (item, "image")) {
+ struct IMAGES **p = &images;
+
+ while (*p)
+ p = &((*p)->next);
+ *p = (struct IMAGES *)malloc (sizeof (struct IMAGES));
+ if (*p == NULL) {
+ prom_printf("malloc error in cfg_set\n");
+ return -1;
+ }
+ (*p)->next = 0;
+ curr_table = ((*p)->table);
+ memcpy (curr_table, cf_image, sizeof (cf_image));
+ }
+ for (walk = curr_table; walk->type != cft_end; walk++) {
+ if (walk->name && !strcasecmp (walk->name, item)) {
+ if (value && walk->type != cft_strg)
+ cfg_warn ("'%s' doesn't have a value", walk->name);
+ else if (!value && walk->type == cft_strg)
+ cfg_warn ("Value expected for '%s'", walk->name);
+ else {
+ if (walk->data)
+ cfg_warn ("Duplicate entry '%s'", walk->name);
+ if (walk->type == cft_flag)
+ walk->data = &flag_set;
+ else if (walk->type == cft_strg)
+ walk->data = value;
+ }
+ break;
+ }
+ }
+ if (walk->type != cft_end)
+ return 1;
// cfg_return (item, value);
- return 0;
+ return 0;
}
int cfg_parse (char *cfg_file, char *buff, int len)
{
- char *item, *value;
-
- file_name = cfg_file;
- currp = buff;
- endp = currp + len;
-
- if (setjmp (env))
- return -1;
- while (1) {
- if (!cfg_next (&item, &value))
- return 0;
- if (!cfg_set (item, value)) {
+ char *item, *value;
+
+ file_name = cfg_file;
+ currp = buff;
+ endp = currp + len;
+
+ if (setjmp (env))
+ return -1;
+ while (1) {
+ if (!cfg_next (&item, &value))
+ return 0;
+ if (!cfg_set (item, value)) {
#if DEBUG
- prom_printf("Can't set item %s to value %s\n", item, value);
+ prom_printf("Can't set item %s to value %s\n", item, value);
#endif
- }
- free (item);
- }
+ }
+ free (item);
+ }
}
static char *cfg_get_strg_i (CONFIG * table, char *item)
{
- CONFIG *walk;
+ CONFIG *walk;
- for (walk = table; walk->type != cft_end; walk++)
- if (walk->name && !strcasecmp (walk->name, item))
- return walk->data;
- return 0;
+ for (walk = table; walk->type != cft_end; walk++)
+ if (walk->name && !strcasecmp (walk->name, item))
+ return walk->data;
+ return 0;
}
char *cfg_get_strg (char *image, char *item)
{
- struct IMAGES *p;
- char *label, *alias;
- char *ret;
-
- if (!image)
- return cfg_get_strg_i (cf_options, item);
- for (p = images; p; p = p->next) {
- label = cfg_get_strg_i (p->table, "label");
- if (!label) {
- label = cfg_get_strg_i (p->table, "image");
- alias = strrchr (label, '/');
- if (alias)
- label = alias + 1;
- }
- alias = cfg_get_strg_i (p->table, "alias");
- if (!strcmp (label, image) || (alias && !strcmp (alias, image))) {
- ret = cfg_get_strg_i (p->table, item);
- if (!ret)
- ret = cfg_get_strg_i (cf_options, item);
- return ret;
- }
- }
- return 0;
+ struct IMAGES *p;
+ char *label, *alias;
+ char *ret;
+
+ if (!image)
+ return cfg_get_strg_i (cf_options, item);
+ for (p = images; p; p = p->next) {
+ label = cfg_get_strg_i (p->table, "label");
+ if (!label) {
+ label = cfg_get_strg_i (p->table, "image");
+ alias = strrchr (label, '/');
+ if (alias)
+ label = alias + 1;
+ }
+ alias = cfg_get_strg_i (p->table, "alias");
+ if (!strcmp (label, image) || (alias && !strcmp (alias, image))) {
+ ret = cfg_get_strg_i (p->table, item);
+ if (!ret)
+ ret = cfg_get_strg_i (cf_options, item);
+ return ret;
+ }
+ }
+ return 0;
}
int cfg_get_flag (char *image, char *item)
{
- return !!cfg_get_strg (image, item);
+ return !!cfg_get_strg (image, item);
}
static int printl_count = 0;
static void printlabel (char *label, int defflag)
{
- int len = strlen (label);
-
- if (!printl_count)
- prom_printf ("\n");
- prom_printf ("%s %s",defflag?"*":" ", label);
- while (len++ < 25)
- prom_putchar (' ');
- printl_count++;
- if (printl_count == 3)
- printl_count = 0;
+ int len = strlen (label);
+
+ if (!printl_count)
+ prom_printf ("\n");
+ prom_printf ("%s %s",defflag?"*":" ", label);
+ while (len++ < 25)
+ prom_putchar (' ');
+ printl_count++;
+ if (printl_count == 3)
+ printl_count = 0;
}
void cfg_print_images (void)
{
- struct IMAGES *p;
- char *label, *alias;
-
- char *ret = cfg_get_strg_i (cf_options, "default");
- int defflag=0;
-
- printl_count = 0;
- for (p = images; p; p = p->next) {
- label = cfg_get_strg_i (p->table, "label");
- if (!label) {
- label = cfg_get_strg_i (p->table, "image");
- alias = strrchr (label, '/');
- if (alias)
- label = alias + 1;
- }
- if(!strcmp(ret,label))
- defflag=1;
- else
- defflag=0;
- alias = cfg_get_strg_i (p->table, "alias");
- printlabel (label, defflag);
- if (alias)
- printlabel (alias, 0);
- }
- prom_printf("\n");
+ struct IMAGES *p;
+ char *label, *alias;
+
+ char *ret = cfg_get_strg_i (cf_options, "default");
+ int defflag=0;
+
+ printl_count = 0;
+ for (p = images; p; p = p->next) {
+ label = cfg_get_strg_i (p->table, "label");
+ if (!label) {
+ label = cfg_get_strg_i (p->table, "image");
+ alias = strrchr (label, '/');
+ if (alias)
+ label = alias + 1;
+ }
+ if(!strcmp(ret,label))
+ defflag=1;
+ else
+ defflag=0;
+ alias = cfg_get_strg_i (p->table, "alias");
+ printlabel (label, defflag);
+ if (alias)
+ printlabel (alias, 0);
+ }
+ prom_printf("\n");
}
char *cfg_get_default (void)
{
- char *label;
- char *ret = cfg_get_strg_i (cf_options, "default");
-
- if (ret)
- return ret;
- if (!images)
- return 0;
- ret = cfg_get_strg_i (images->table, "label");
- if (!ret) {
- ret = cfg_get_strg_i (images->table, "image");
- label = strrchr (ret, '/');
- if (label)
- ret = label + 1;
- }
- return ret;
+ char *label;
+ char *ret = cfg_get_strg_i (cf_options, "default");
+
+ if (ret)
+ return ret;
+ if (!images)
+ return 0;
+ ret = cfg_get_strg_i (images->table, "label");
+ if (!ret) {
+ ret = cfg_get_strg_i (images->table, "image");
+ label = strrchr (ret, '/');
+ if (label)
+ ret = label + 1;
+ }
+ return ret;
}
+
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
*ptr = 0;
result->dev = strdup(ipath);
} else
- result->dev = strdup(ipath);
+ result->dev = strdup(ipath);
else if ((ptr = strchr(ipath, ':')) != NULL) {
*ptr = 0;
result->dev = strdup(ipath);
return 0;
}
- punt:
+punt:
if (!result->dev)
result->dev = strdup(defdev);
const char* file_name,
int partition)
{
- struct partition_t* parts;
- struct partition_t* p;
- struct partition_t* found;
+ struct partition_t* parts;
+ struct partition_t* p;
+ struct partition_t* found;
- parts = partitions_lookup(dev_name);
- found = NULL;
+ parts = partitions_lookup(dev_name);
+ found = NULL;
#if DEBUG
- if (parts)
- prom_printf("partitions:\n");
- else
- prom_printf("no partitions found.\n");
+ if (parts)
+ prom_printf("partitions:\n");
+ else
+ prom_printf("no partitions found.\n");
#endif
- for (p = parts; p && !found; p=p->next) {
- DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
- p->part_number, p->part_start, p->part_size );
- if (partition == -1) {
- file->fs = fs_open( file, dev_name, p, file_name );
- if (file->fs != NULL)
- goto bail;
- }
- if ((partition >= 0) && (partition == p->part_number))
- found = p;
+ for (p = parts; p && !found; p=p->next) {
+ DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
+ p->part_number, p->part_start, p->part_size );
+ if (partition == -1) {
+ file->fs = fs_open( file, dev_name, p, file_name );
+ if (file->fs != NULL)
+ goto bail;
+ }
+ if ((partition >= 0) && (partition == p->part_number))
+ found = p;
#if DEBUG
- if (found)
- prom_printf(" (match)\n");
+ if (found)
+ prom_printf(" (match)\n");
#endif
- }
+ }
- /* Note: we don't skip when found is NULL since we can, in some
- * cases, let OF figure out a default partition.
- */
- DEBUG_F( "Using OF defaults.. (found = %p)\n", found );
- file->fs = fs_open( file, dev_name, found, file_name );
+ /* Note: we don't skip when found is NULL since we can, in some
+ * cases, let OF figure out a default partition.
+ */
+ DEBUG_F( "Using OF defaults.. (found = %p)\n", found );
+ file->fs = fs_open( file, dev_name, found, file_name );
bail:
- if (parts)
- partitions_free(parts);
+ if (parts)
+ partitions_free(parts);
- return fserrorno;
+ return fserrorno;
}
static int
const char* dev_name,
const char* file_name)
{
- file->fs = fs_of_netboot;
- return fs_of_netboot->open(file, dev_name, NULL, file_name);
+ file->fs = fs_of_netboot;
+ return fs_of_netboot->open(file, dev_name, NULL, file_name);
}
static int
unsigned int size,
void* buffer)
{
- prom_printf("WARNING ! default_read called !\n");
- return FILE_ERR_EOF;
+ prom_printf("WARNING ! default_read called !\n");
+ return FILE_ERR_EOF;
}
static int
default_seek( struct boot_file_t* file,
unsigned int newpos)
{
- prom_printf("WARNING ! default_seek called !\n");
- return FILE_ERR_EOF;
+ prom_printf("WARNING ! default_seek called !\n");
+ return FILE_ERR_EOF;
}
static int
default_close( struct boot_file_t* file)
{
- prom_printf("WARNING ! default_close called !\n");
- return FILE_ERR_OK;
+ prom_printf("WARNING ! default_close called !\n");
+ return FILE_ERR_OK;
}
static struct fs_t fs_default =
{
- "defaults",
- NULL,
- default_read,
- default_seek,
- default_close
+ "defaults",
+ NULL,
+ default_read,
+ default_seek,
+ default_close
};
int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file)
{
- int result;
+ int result;
- memset(file, 0, sizeof(struct boot_file_t*));
- file->fs = &fs_default;
+ memset(file, 0, sizeof(struct boot_file_t*));
+ file->fs = &fs_default;
- DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n",
- spec->dev, spec->file, spec->part);
+ DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n",
+ spec->dev, spec->file, spec->part);
- result = prom_get_devtype(spec->dev);
- if (result > 0)
- file->device_kind = result;
- else
- return result;
+ result = prom_get_devtype(spec->dev);
+ if (result > 0)
+ file->device_kind = result;
+ else
+ return result;
- switch(file->device_kind) {
- case FILE_DEVICE_BLOCK:
- DEBUG_F("device is a block device\n");
- return file_block_open(file, spec->dev, spec->file, spec->part);
- case FILE_DEVICE_NET:
- DEBUG_F("device is a network device\n");
- return file_net_open(file, spec->dev, spec->file);
- }
- return 0;
+ switch(file->device_kind) {
+ case FILE_DEVICE_BLOCK:
+ DEBUG_F("device is a block device\n");
+ return file_block_open(file, spec->dev, spec->file, spec->part);
+ case FILE_DEVICE_NET:
+ DEBUG_F("device is a network device\n");
+ return file_net_open(file, spec->dev, spec->file);
+ }
+ return 0;
}
/*
/* Filesystem handlers yaboot knows about */
static const struct fs_t *block_filesystems[] = {
- &ext2_filesystem, /* ext2 */
+ &ext2_filesystem, /* ext2 */
#ifdef CONFIG_FS_XFS
- &xfs_filesystem, /* XFS */
+ &xfs_filesystem, /* XFS */
#endif /* CONFIG_FS_XFS */
#ifdef CONFIG_FS_REISERFS
- &reiserfs_filesystem, /* reiserfs */
+ &reiserfs_filesystem, /* reiserfs */
#endif /* CONFIG_FS_REISERFS */
- &of_filesystem, /* HFS/HFS+, ISO9660, UDF, UFS */
- NULL
+ &of_filesystem, /* HFS/HFS+, ISO9660, UDF, UFS */
+ NULL
};
const struct fs_t *fs_of = &of_filesystem; /* needed by ISO9660 */
return *fs;
}
+
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
struct fs_t ext2_filesystem =
{
- "ext2",
- ext2_open,
- ext2_read,
- ext2_seek,
- ext2_close
+ "ext2",
+ ext2_open,
+ ext2_read,
+ ext2_seek,
+ ext2_close
};
/* IO manager structure for the ext2 library */
static struct struct_io_manager struct_linux_manager =
{
- EXT2_ET_MAGIC_IO_MANAGER,
- "linux I/O Manager",
- linux_open,
- linux_close,
- linux_set_blksize,
- linux_read_blk,
- linux_write_blk,
- linux_flush
+ EXT2_ET_MAGIC_IO_MANAGER,
+ "linux I/O Manager",
+ linux_open,
+ linux_close,
+ linux_set_blksize,
+ linux_read_blk,
+ linux_write_blk,
+ linux_flush
};
static io_manager linux_io_manager = &struct_linux_manager;
void com_err (const char *a, long i, const char *fmt,...)
{
- prom_printf ((char *) fmt);
+ prom_printf ((char *) fmt);
}
static int
struct partition_t* part,
const char* file_name)
{
- int result = 0;
- int error = FILE_ERR_NOTFOUND;
- static char buffer[1024];
- int ofopened = 0;
+ int result = 0;
+ int error = FILE_ERR_NOTFOUND;
+ static char buffer[1024];
+ int ofopened = 0;
- DEBUG_ENTER;
- DEBUG_OPEN;
-
- if (opened) {
- prom_printf("ext2_open() : fs busy\n");
- DEBUG_LEAVE(FILE_ERR_FSBUSY);
- return FILE_ERR_FSBUSY;
- }
- if (file->device_kind != FILE_DEVICE_BLOCK) {
- prom_printf("Can't open ext2 filesystem on non-block device\n");
- DEBUG_LEAVE(FILE_ERR_BADDEV);
- return FILE_ERR_BADDEV;
- }
-
- fs = NULL;
+ DEBUG_ENTER;
+ DEBUG_OPEN;
+
+ if (opened) {
+ prom_printf("ext2_open() : fs busy\n");
+ DEBUG_LEAVE(FILE_ERR_FSBUSY);
+ return FILE_ERR_FSBUSY;
+ }
+ if (file->device_kind != FILE_DEVICE_BLOCK) {
+ prom_printf("Can't open ext2 filesystem on non-block device\n");
+ DEBUG_LEAVE(FILE_ERR_BADDEV);
+ return FILE_ERR_BADDEV;
+ }
+
+ fs = NULL;
- /* We don't care too much about the device block size since we run
- * thru the deblocker. We may have to change that is we plan to be
- * compatible with older versions of OF
- */
- bs = 1024;
- doff = 0;
- if (part)
- doff = (unsigned long long)(part->part_start) * part->blocksize;
- cur_file = file;
+ /* We don't care too much about the device block size since we run
+ * thru the deblocker. We may have to change that is we plan to be
+ * compatible with older versions of OF
+ */
+ bs = 1024;
+ doff = 0;
+ if (part)
+ doff = (unsigned long long)(part->part_start) * part->blocksize;
+ cur_file = file;
- DEBUG_F("partition offset: %Lu\n", doff);
+ DEBUG_F("partition offset: %Lu\n", doff);
- /* Open the OF device for the entire disk */
- strncpy(buffer, dev_name, 1020);
- strcat(buffer, ":0");
+ /* Open the OF device for the entire disk */
+ strncpy(buffer, dev_name, 1020);
+ strcat(buffer, ":0");
- DEBUG_F("<%s>\n", buffer);
+ DEBUG_F("<%s>\n", buffer);
- file->of_device = prom_open(buffer);
+ file->of_device = prom_open(buffer);
- DEBUG_F("file->of_device = %p\n", file->of_device);
+ DEBUG_F("file->of_device = %p\n", file->of_device);
- if (file->of_device == PROM_INVALID_HANDLE) {
+ if (file->of_device == PROM_INVALID_HANDLE) {
- DEBUG_F("Can't open device %p\n", file->of_device);
- DEBUG_LEAVE(FILE_IOERR);
- return FILE_IOERR;
- }
- ofopened = 1;
+ DEBUG_F("Can't open device %p\n", file->of_device);
+ DEBUG_LEAVE(FILE_IOERR);
+ return FILE_IOERR;
+ }
+ ofopened = 1;
- /* Open the ext2 filesystem */
- result = ext2fs_open (buffer, EXT2_FLAG_RW, 0, 0, linux_io_manager, &fs);
- if (result) {
-
- if(result == EXT2_ET_BAD_MAGIC)
- {
- DEBUG_F( "ext2fs_open returned bad magic loading file %p\n",
- file );
- }
- else
- {
- DEBUG_F( "ext2fs_open error #%d while loading file %s\n",
- result, file_name);
- }
- error = FILE_ERR_BAD_FSYS;
- goto bail;
- }
-
- /* Allocate the block buffer */
- block_buffer = malloc(fs->blocksize * 2);
- if (!block_buffer) {
-
- DEBUG_F("ext2fs: can't alloc block buffer (%d bytes)\n", fs->blocksize * 2);
- error = FILE_IOERR;
- goto bail;
- }
+ /* Open the ext2 filesystem */
+ result = ext2fs_open (buffer, EXT2_FLAG_RW, 0, 0, linux_io_manager, &fs);
+ if (result) {
+
+ if(result == EXT2_ET_BAD_MAGIC)
+ {
+ DEBUG_F( "ext2fs_open returned bad magic loading file %p\n",
+ file );
+ }
+ else
+ {
+ DEBUG_F( "ext2fs_open error #%d while loading file %s\n",
+ result, file_name);
+ }
+ error = FILE_ERR_BAD_FSYS;
+ goto bail;
+ }
+
+ /* Allocate the block buffer */
+ block_buffer = malloc(fs->blocksize * 2);
+ if (!block_buffer) {
+
+ DEBUG_F("ext2fs: can't alloc block buffer (%d bytes)\n", fs->blocksize * 2);
+ error = FILE_IOERR;
+ goto bail;
+ }
- /* Lookup file by pathname */
- root = cwd = EXT2_ROOT_INO;
- result = ext2fs_namei_follow(fs, root, cwd, file_name, &file->inode);
- if (result) {
-
- DEBUG_F("ext2fs_namei error #%d while loading file %s\n", result, file_name);
- if (result == EXT2_ET_SYMLINK_LOOP)
- error = FILE_ERR_SYMLINK_LOOP;
- else if (result == EXT2_ET_FILE_NOT_FOUND)
- error = FILE_ERR_NOTFOUND;
- else
- error = FILE_IOERR;
- goto bail;
- }
+ /* Lookup file by pathname */
+ root = cwd = EXT2_ROOT_INO;
+ result = ext2fs_namei_follow(fs, root, cwd, file_name, &file->inode);
+ if (result) {
+
+ DEBUG_F("ext2fs_namei error #%d while loading file %s\n", result, file_name);
+ if (result == EXT2_ET_SYMLINK_LOOP)
+ error = FILE_ERR_SYMLINK_LOOP;
+ else if (result == EXT2_ET_FILE_NOT_FOUND)
+ error = FILE_ERR_NOTFOUND;
+ else
+ error = FILE_IOERR;
+ goto bail;
+ }
#if 0
- result = ext2fs_follow_link(fs, root, cwd, file->inode, &file->inode);
- if (result) {
+ result = ext2fs_follow_link(fs, root, cwd, file->inode, &file->inode);
+ if (result) {
- DEBUG_F("ext2fs_follow_link error #%d while loading file %s\n", result, file_name);
- error = FILE_ERR_NOTFOUND;
- goto bail;
- }
+ DEBUG_F("ext2fs_follow_link error #%d while loading file %s\n", result, file_name);
+ error = FILE_ERR_NOTFOUND;
+ goto bail;
+ }
#endif
#ifndef FAST_VERSION
- result = ext2fs_read_inode(fs, file->inode, &cur_inode);
- if (result) {
-
- DEBUG_F("ext2fs_read_inode error #%d while loading file %s\n", result, file_name);
- if (result == EXT2_ET_FILE_TOO_BIG)
- error = FILE_ERR_LENGTH;
- else if (result == EXT2_ET_LLSEEK_FAILED)
- error = FILE_CANT_SEEK;
- else if (result == EXT2_ET_FILE_NOT_FOUND)
- error = FILE_ERR_NOTFOUND;
- else
- error = FILE_IOERR;
- goto bail;
- }
+ result = ext2fs_read_inode(fs, file->inode, &cur_inode);
+ if (result) {
+
+ DEBUG_F("ext2fs_read_inode error #%d while loading file %s\n", result, file_name);
+ if (result == EXT2_ET_FILE_TOO_BIG)
+ error = FILE_ERR_LENGTH;
+ else if (result == EXT2_ET_LLSEEK_FAILED)
+ error = FILE_CANT_SEEK;
+ else if (result == EXT2_ET_FILE_NOT_FOUND)
+ error = FILE_ERR_NOTFOUND;
+ else
+ error = FILE_IOERR;
+ goto bail;
+ }
#endif /* FAST_VERSION */
- file->pos = 0;
+ file->pos = 0;
- opened = 1;
+ opened = 1;
bail:
- if (!opened) {
- if (fs)
- ext2fs_close(fs);
- fs = NULL;
- if (ofopened)
- prom_close(file->of_device);
- if (block_buffer)
- free(block_buffer);
- block_buffer = NULL;
- cur_file = NULL;
+ if (!opened) {
+ if (fs)
+ ext2fs_close(fs);
+ fs = NULL;
+ if (ofopened)
+ prom_close(file->of_device);
+ if (block_buffer)
+ free(block_buffer);
+ block_buffer = NULL;
+ cur_file = NULL;
- DEBUG_LEAVE_F(error);
- return error;
- }
+ DEBUG_LEAVE_F(error);
+ return error;
+ }
- DEBUG_LEAVE(FILE_ERR_OK);
- return FILE_ERR_OK;
+ DEBUG_LEAVE(FILE_ERR_OK);
+ return FILE_ERR_OK;
}
#ifdef FAST_VERSION
static int
read_dump_range(void)
{
- int count = read_range_count;
- int size;
+ int count = read_range_count;
+ int size;
#ifdef VERBOSE_DEBUG
- DEBUG_F(" dumping range: start: 0x%x count: 0x%x\n",
- read_range_count, read_range_start);
+ DEBUG_F(" dumping range: start: 0x%x count: 0x%x\n",
+ read_range_count, read_range_start);
#endif
- /* Check if we need to handle a special case for the last block */
- if ((count * bs) > read_max)
- count--;
- if (count) {
- size = count * bs;
- read_result = io_channel_read_blk(fs->io, read_range_start, count, read_buffer);
- if (read_result)
- return BLOCK_ABORT;
- read_buffer += size;
- read_max -= size;
- read_total += size;
- read_cur_file->pos += size;
- read_range_count -= count;
- read_range_start += count;
- read_last_logical += count;
- }
- /* Handle remaining block */
- if (read_max && read_range_count) {
- read_result = io_channel_read_blk(fs->io, read_range_start, 1, block_buffer);
- if (read_result)
- return BLOCK_ABORT;
- memcpy(read_buffer, block_buffer, read_max);
- read_cur_file->pos += read_max;
- read_total += read_max;
- read_max = 0;
- }
- read_range_count = read_range_start = 0;
-
- return (read_max == 0) ? BLOCK_ABORT : 0;
+ /* Check if we need to handle a special case for the last block */
+ if ((count * bs) > read_max)
+ count--;
+ if (count) {
+ size = count * bs;
+ read_result = io_channel_read_blk(fs->io, read_range_start, count, read_buffer);
+ if (read_result)
+ return BLOCK_ABORT;
+ read_buffer += size;
+ read_max -= size;
+ read_total += size;
+ read_cur_file->pos += size;
+ read_range_count -= count;
+ read_range_start += count;
+ read_last_logical += count;
+ }
+ /* Handle remaining block */
+ if (read_max && read_range_count) {
+ read_result = io_channel_read_blk(fs->io, read_range_start, 1, block_buffer);
+ if (read_result)
+ return BLOCK_ABORT;
+ memcpy(read_buffer, block_buffer, read_max);
+ read_cur_file->pos += read_max;
+ read_total += read_max;
+ read_max = 0;
+ }
+ read_range_count = read_range_start = 0;
+
+ return (read_max == 0) ? BLOCK_ABORT : 0;
}
static int
read_iterator(ext2_filsys fs, blk_t *blocknr, int lg_block, void *private)
{
#ifdef VERBOSE_DEBUG
- DEBUG_F("read_it: p_bloc: 0x%x, l_bloc: 0x%x, f_pos: 0x%x, rng_pos: 0x%x ",
- *blocknr, lg_block, read_cur_file->pos, read_last_logical);
+ DEBUG_F("read_it: p_bloc: 0x%x, l_bloc: 0x%x, f_pos: 0x%x, rng_pos: 0x%x ",
+ *blocknr, lg_block, read_cur_file->pos, read_last_logical);
#endif
- if (lg_block < 0) {
+ if (lg_block < 0) {
#ifdef VERBOSE_DEBUG
- DEBUG_F(" <skip lg>\n");
+ DEBUG_F(" <skip lg>\n");
#endif
- return 0;
- }
+ return 0;
+ }
- /* If we have not reached the start block yet, we skip */
- if (lg_block < read_cur_file->pos / bs) {
+ /* If we have not reached the start block yet, we skip */
+ if (lg_block < read_cur_file->pos / bs) {
#ifdef VERBOSE_DEBUG
- DEBUG_F(" <skip pos>\n");
+ DEBUG_F(" <skip pos>\n");
#endif
- return 0;
- }
-
- /* If block is contiguous to current range, just extend range,
- * exit if we pass the remaining bytes count to read
- */
- if (read_range_start && read_range_count < MAX_READ_RANGE
- && (*blocknr == read_range_start + read_range_count)
- && (lg_block == read_last_logical + read_range_count)) {
+ return 0;
+ }
+
+ /* If block is contiguous to current range, just extend range,
+ * exit if we pass the remaining bytes count to read
+ */
+ if (read_range_start && read_range_count < MAX_READ_RANGE
+ && (*blocknr == read_range_start + read_range_count)
+ && (lg_block == read_last_logical + read_range_count)) {
#ifdef VERBOSE_DEBUG
- DEBUG_F(" block in range\n");
+ DEBUG_F(" block in range\n");
#endif
- ++read_range_count;
- return ((read_range_count * bs) >= read_max) ? BLOCK_ABORT : 0;
- }
+ ++read_range_count;
+ return ((read_range_count * bs) >= read_max) ? BLOCK_ABORT : 0;
+ }
- /* Range doesn't match. Dump existing range */
- if (read_range_start) {
+ /* Range doesn't match. Dump existing range */
+ if (read_range_start) {
#ifdef VERBOSE_DEBUG
- DEBUG_F(" calling dump range \n");
+ DEBUG_F(" calling dump range \n");
#endif
- if (read_dump_range())
- return BLOCK_ABORT;
- }
+ if (read_dump_range())
+ return BLOCK_ABORT;
+ }
- /* Here we handle holes in the file */
- if (lg_block && lg_block != read_last_logical) {
- unsigned long nzero;
+ /* Here we handle holes in the file */
+ if (lg_block && lg_block != read_last_logical) {
+ unsigned long nzero;
#ifdef VERBOSE_DEBUG
- DEBUG_F(" hole from lg_bloc 0x%x\n", read_last_logical);
+ DEBUG_F(" hole from lg_bloc 0x%x\n", read_last_logical);
#endif
- if (read_cur_file->pos % bs) {
- int offset = read_cur_file->pos % bs;
- int size = bs - offset;
- if (size > read_max)
- size = read_max;
- memset(read_buffer, 0, size);
- read_max -= size;
- read_total += size;
- read_buffer += size;
- read_cur_file->pos += size;
- ++read_last_logical;
- if (read_max == 0)
- return BLOCK_ABORT;
- }
- nzero = (lg_block - read_last_logical) * bs;
- if (nzero) {
- if (nzero > read_max)
- nzero = read_max;
- memset(read_buffer, 0, nzero);
- read_max -= nzero;
- read_total += nzero;
- read_buffer += nzero;
- read_cur_file->pos += nzero;
- if (read_max == 0)
- return BLOCK_ABORT;
- }
- read_last_logical = lg_block;
- }
+ if (read_cur_file->pos % bs) {
+ int offset = read_cur_file->pos % bs;
+ int size = bs - offset;
+ if (size > read_max)
+ size = read_max;
+ memset(read_buffer, 0, size);
+ read_max -= size;
+ read_total += size;
+ read_buffer += size;
+ read_cur_file->pos += size;
+ ++read_last_logical;
+ if (read_max == 0)
+ return BLOCK_ABORT;
+ }
+ nzero = (lg_block - read_last_logical) * bs;
+ if (nzero) {
+ if (nzero > read_max)
+ nzero = read_max;
+ memset(read_buffer, 0, nzero);
+ read_max -= nzero;
+ read_total += nzero;
+ read_buffer += nzero;
+ read_cur_file->pos += nzero;
+ if (read_max == 0)
+ return BLOCK_ABORT;
+ }
+ read_last_logical = lg_block;
+ }
/* If we are not aligned, handle that case */
- if (read_cur_file->pos % bs) {
- int offset = read_cur_file->pos % bs;
- int size = bs - offset;
+ if (read_cur_file->pos % bs) {
+ int offset = read_cur_file->pos % bs;
+ int size = bs - offset;
#ifdef VERBOSE_DEBUG
- DEBUG_F(" handle unaligned start\n");
+ DEBUG_F(" handle unaligned start\n");
#endif
- read_result = io_channel_read_blk(fs->io, *blocknr, 1, block_buffer);
- if (read_result)
- return BLOCK_ABORT;
- if (size > read_max)
- size = read_max;
- memcpy(read_buffer, block_buffer + offset, size);
- read_cur_file->pos += size;
- read_max -= size;
- read_total += size;
- read_buffer += size;
- read_last_logical = lg_block + 1;
- return (read_max == 0) ? BLOCK_ABORT : 0;
- }
-
- /* If there is still a physical block to add, then create a new range */
- if (*blocknr) {
+ read_result = io_channel_read_blk(fs->io, *blocknr, 1, block_buffer);
+ if (read_result)
+ return BLOCK_ABORT;
+ if (size > read_max)
+ size = read_max;
+ memcpy(read_buffer, block_buffer + offset, size);
+ read_cur_file->pos += size;
+ read_max -= size;
+ read_total += size;
+ read_buffer += size;
+ read_last_logical = lg_block + 1;
+ return (read_max == 0) ? BLOCK_ABORT : 0;
+ }
+
+ /* If there is still a physical block to add, then create a new range */
+ if (*blocknr) {
#ifdef VERBOSE_DEBUG
- DEBUG_F(" new range\n");
+ DEBUG_F(" new range\n");
#endif
- read_range_start = *blocknr;
- read_range_count = 1;
- return (bs >= read_max) ? BLOCK_ABORT : 0;
- }
+ read_range_start = *blocknr;
+ read_range_count = 1;
+ return (bs >= read_max) ? BLOCK_ABORT : 0;
+ }
#ifdef VERBOSE_DEBUG
- DEBUG_F("\n");
+ DEBUG_F("\n");
#endif
- return 0;
+ return 0;
}
#endif /* FAST_VERSION */
unsigned int size,
void* buffer)
{
- errcode_t retval;
+ errcode_t retval;
#ifdef FAST_VERSION
- if (!opened)
- return FILE_IOERR;
+ if (!opened)
+ return FILE_IOERR;
- DEBUG_F("ext_read() from pos 0x%Lx, size: 0x%ux\n", file->pos, size);
+ DEBUG_F("ext_read() from pos 0x%Lx, size: 0x%ux\n", file->pos, size);
- read_cur_file = file;
- read_range_start = 0;
- read_range_count = 0;
- read_last_logical = file->pos / bs;
- read_total = 0;
- read_max = size;
- read_buffer = (unsigned char*)buffer;
- read_result = 0;
+ read_cur_file = file;
+ read_range_start = 0;
+ read_range_count = 0;
+ read_last_logical = file->pos / bs;
+ read_total = 0;
+ read_max = size;
+ read_buffer = (unsigned char*)buffer;
+ read_result = 0;
- retval = ext2fs_block_iterate(fs, file->inode, 0, 0, read_iterator, 0);
- if (retval == BLOCK_ABORT)
- retval = read_result;
- if (!retval && read_range_start) {
+ retval = ext2fs_block_iterate(fs, file->inode, 0, 0, read_iterator, 0);
+ if (retval == BLOCK_ABORT)
+ retval = read_result;
+ if (!retval && read_range_start) {
#ifdef VERBOSE_DEBUG
- DEBUG_F("on exit: range_start is 0x%x, calling dump...\n",
- read_range_start);
+ DEBUG_F("on exit: range_start is 0x%x, calling dump...\n",
+ read_range_start);
#endif
- read_dump_range();
- retval = read_result;
- }
- if (retval)
- prom_printf ("ext2: i/o error %ld in read\n", (long) retval);
+ read_dump_range();
+ retval = read_result;
+ }
+ if (retval)
+ prom_printf ("ext2: i/o error %ld in read\n", (long) retval);
- return read_total;
+ return read_total;
#else /* FAST_VERSION */
- int status;
- unsigned int read = 0;
+ int status;
+ unsigned int read = 0;
- if (!opened)
- return FILE_IOERR;
+ if (!opened)
+ return FILE_IOERR;
- DEBUG_F("ext_read() from pos 0x%x, size: 0x%x\n", file->pos, size);
+ DEBUG_F("ext_read() from pos 0x%x, size: 0x%x\n", file->pos, size);
- while(size) {
- blk_t fblock = file->pos / bs;
- blk_t pblock;
- unsigned int blkorig, s, b;
+ while(size) {
+ blk_t fblock = file->pos / bs;
+ blk_t pblock;
+ unsigned int blkorig, s, b;
- pblock = 0;
- status = ext2fs_bmap(fs, file->inode, &cur_inode,
- block_buffer, 0, fblock, &pblock);
- if (status) {
-
- DEBUG_F("ext2fs_bmap(fblock:%d) return: %d\n", fblock, status);
- return read;
- }
- blkorig = fblock * bs;
- b = file->pos - blkorig;
- s = ((bs - b) > size) ? size : (bs - b);
- if (pblock) {
- unsigned long long pos =
- ((unsigned long long)pblock) * (unsigned long long)bs;
- pos += doff;
- prom_lseek(file->of_device, pos);
- status = prom_read(file->of_device, block_buffer, bs);
- if (status != bs) {
+ pblock = 0;
+ status = ext2fs_bmap(fs, file->inode, &cur_inode,
+ block_buffer, 0, fblock, &pblock);
+ if (status) {
+
+ DEBUG_F("ext2fs_bmap(fblock:%d) return: %d\n", fblock, status);
+ return read;
+ }
+ blkorig = fblock * bs;
+ b = file->pos - blkorig;
+ s = ((bs - b) > size) ? size : (bs - b);
+ if (pblock) {
+ unsigned long long pos =
+ ((unsigned long long)pblock) * (unsigned long long)bs;
+ pos += doff;
+ prom_lseek(file->of_device, pos);
+ status = prom_read(file->of_device, block_buffer, bs);
+ if (status != bs) {
prom_printf("ext2: io error in read, ex: %d, got: %d\n",
- bs, status);
+ bs, status);
return read;
- }
- } else
- memset(block_buffer, 0, bs);
-
- memcpy(buffer, block_buffer + b, s);
- read += s;
- size -= s;
- buffer += s;
- file->pos += s;
- }
- return read;
+ }
+ } else
+ memset(block_buffer, 0, bs);
+
+ memcpy(buffer, block_buffer + b, s);
+ read += s;
+ size -= s;
+ buffer += s;
+ file->pos += s;
+ }
+ return read;
#endif /* FAST_VERSION */
}
ext2_seek( struct boot_file_t* file,
unsigned int newpos)
{
- if (!opened)
- return FILE_CANT_SEEK;
+ if (!opened)
+ return FILE_CANT_SEEK;
- file->pos = newpos;
- return FILE_ERR_OK;
+ file->pos = newpos;
+ return FILE_ERR_OK;
}
static int
ext2_close( struct boot_file_t* file)
{
- if (!opened)
- return FILE_IOERR;
+ if (!opened)
+ return FILE_IOERR;
- if (block_buffer)
- free(block_buffer);
- block_buffer = NULL;
+ if (block_buffer)
+ free(block_buffer);
+ block_buffer = NULL;
- if (fs)
- ext2fs_close(fs);
- fs = NULL;
+ if (fs)
+ ext2fs_close(fs);
+ fs = NULL;
- prom_close(file->of_device);
- DEBUG_F("ext2_close called\n");
+ prom_close(file->of_device);
+ DEBUG_F("ext2_close called\n");
- opened = 0;
+ opened = 0;
- return 0;
+ return 0;
}
static errcode_t linux_open (const char *name, int flags, io_channel * channel)
{
- io_channel io;
-
-
- if (!name)
- return EXT2_ET_BAD_DEVICE_NAME;
- io = (io_channel) malloc (sizeof (struct struct_io_channel));
- if (!io)
- return EXT2_ET_BAD_DEVICE_NAME;
- memset (io, 0, sizeof (struct struct_io_channel));
- io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
- io->manager = linux_io_manager;
- io->name = (char *) malloc (strlen (name) + 1);
- strcpy (io->name, name);
- io->block_size = bs;
- io->read_error = 0;
- io->write_error = 0;
- *channel = io;
-
- return 0;
+ io_channel io;
+
+
+ if (!name)
+ return EXT2_ET_BAD_DEVICE_NAME;
+ io = (io_channel) malloc (sizeof (struct struct_io_channel));
+ if (!io)
+ return EXT2_ET_BAD_DEVICE_NAME;
+ memset (io, 0, sizeof (struct struct_io_channel));
+ io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
+ io->manager = linux_io_manager;
+ io->name = (char *) malloc (strlen (name) + 1);
+ strcpy (io->name, name);
+ io->block_size = bs;
+ io->read_error = 0;
+ io->write_error = 0;
+ *channel = io;
+
+ return 0;
}
static errcode_t linux_close (io_channel channel)
{
- free(channel);
- return 0;
+ free(channel);
+ return 0;
}
static errcode_t linux_set_blksize (io_channel channel, int blksize)
{
- channel->block_size = bs = blksize;
- if (block_buffer) {
- free(block_buffer);
- block_buffer = malloc(bs * 2);
- }
- return 0;
+ channel->block_size = bs = blksize;
+ if (block_buffer) {
+ free(block_buffer);
+ block_buffer = malloc(bs * 2);
+ }
+ return 0;
}
static errcode_t linux_read_blk (io_channel channel, unsigned long block, int count, void *data)
{
- int size;
- unsigned long long tempb;
+ int size;
+ unsigned long long tempb;
- if (count == 0)
- return 0;
+ if (count == 0)
+ return 0;
- tempb = (((unsigned long long) block) *
- ((unsigned long long)bs)) + (unsigned long long)doff;
- size = (count < 0) ? -count : count * bs;
- prom_lseek(cur_file->of_device, tempb);
- if (prom_read(cur_file->of_device, data, size) != size) {
- DEBUG_F("\nRead error on block %ld\n", block);
- return EXT2_ET_SHORT_READ;
- }
- return 0;
+ tempb = (((unsigned long long) block) *
+ ((unsigned long long)bs)) + (unsigned long long)doff;
+ size = (count < 0) ? -count : count * bs;
+ prom_lseek(cur_file->of_device, tempb);
+ if (prom_read(cur_file->of_device, data, size) != size) {
+ DEBUG_F("\nRead error on block %ld\n", block);
+ return EXT2_ET_SHORT_READ;
+ }
+ return 0;
}
static errcode_t linux_write_blk (io_channel channel, unsigned long block, int count, const void *data)
{
- return 0;
+ return 0;
}
static errcode_t linux_flush (io_channel channel)
{
- return 0;
+ return 0;
}
+
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
struct fs_t iso_filesystem =
{
- "iso9660",
- iso_open,
- iso_read,
- iso_seek,
- iso_close
+ "iso9660",
+ iso_open,
+ iso_read,
+ iso_seek,
+ iso_close
};
static int
struct partition_t* part,
const char* file_name)
{
- return FILE_ERR_BAD_FSYS;
+ return FILE_ERR_BAD_FSYS;
}
static int
unsigned int size,
void* buffer)
{
- return FILE_ERR_BAD_FSYS;
+ return FILE_ERR_BAD_FSYS;
}
static int
iso_seek( struct boot_file_t* file,
unsigned int newpos)
{
- return FILE_ERR_BAD_FSYS;
+ return FILE_ERR_BAD_FSYS;
}
static int
iso_close( struct boot_file_t* file)
{
- return 0;
+ return 0;
}
+
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
int
isonum_711 (char * p)
{
- return (*p & 0xff);
+ return (*p & 0xff);
}
int
isonum_712 (char * p)
{
- int val;
+ int val;
- val = *p;
- if (val & 0x80)
- val |= 0xffffff00;
- return (val);
+ val = *p;
+ if (val & 0x80)
+ val |= 0xffffff00;
+ return (val);
}
int
isonum_721 (char * p)
{
- return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
+ return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
}
int
isonum_722 (char * p)
{
- return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
+ return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
}
int
isonum_723 (char * p)
{
#if 0
- if (p[0] != p[3] || p[1] != p[2]) {
- fprintf (stderr, "invalid format 7.2.3 number\n");
- exit (1);
- }
+ if (p[0] != p[3] || p[1] != p[2]) {
+ fprintf (stderr, "invalid format 7.2.3 number\n");
+ exit (1);
+ }
#endif
- return (isonum_721 (p));
+ return (isonum_721 (p));
}
int
isonum_731 (char * p)
{
- return ((p[0] & 0xff)
- | ((p[1] & 0xff) << 8)
- | ((p[2] & 0xff) << 16)
- | ((p[3] & 0xff) << 24));
+ return ((p[0] & 0xff)
+ | ((p[1] & 0xff) << 8)
+ | ((p[2] & 0xff) << 16)
+ | ((p[3] & 0xff) << 24));
}
int
isonum_732 (char * p)
{
- return (((p[0] & 0xff) << 24)
- | ((p[1] & 0xff) << 16)
- | ((p[2] & 0xff) << 8)
- | (p[3] & 0xff));
+ return (((p[0] & 0xff) << 24)
+ | ((p[1] & 0xff) << 16)
+ | ((p[2] & 0xff) << 8)
+ | (p[3] & 0xff));
}
int
isonum_733 (char * p)
{
#if 0
- int i;
+ int i;
- for (i = 0; i < 4; i++) {
- if (p[i] != p[7-i]) {
- fprintf (stderr, "bad format 7.3.3 number\n");
- exit (1);
- }
- }
+ for (i = 0; i < 4; i++) {
+ if (p[i] != p[7-i]) {
+ fprintf (stderr, "bad format 7.3.3 number\n");
+ exit (1);
+ }
+ }
#endif
- return (isonum_731 (p));
+ return (isonum_731 (p));
}
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 8
+ * End:
+ */
#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
static const char *valid_mac_partition_types[] = {
- "apple_unix_svr2",
- "linux",
- "apple_hfs",
- "apple_boot",
- "apple_bootstrap",
- NULL
+ "apple_unix_svr2",
+ "linux",
+ "apple_hfs",
+ "apple_boot",
+ "apple_bootstrap",
+ NULL
};
#endif
const char *part_name, unsigned long part_start, unsigned long part_size,
unsigned short part_blocksize)
{
- struct partition_t* part;
- part = (struct partition_t*)malloc(sizeof(struct partition_t));
+ struct partition_t* part;
+ part = (struct partition_t*)malloc(sizeof(struct partition_t));
- part->part_number = part_number;
- strncpy(part->part_type, part_type, MAX_PART_NAME);
- strncpy(part->part_name, part_name, MAX_PART_NAME);
- part->part_start = part_start;
- part->part_size = part_size;
- part->blocksize = part_blocksize;
+ part->part_number = part_number;
+ strncpy(part->part_type, part_type, MAX_PART_NAME);
+ strncpy(part->part_name, part_name, MAX_PART_NAME);
+ part->part_start = part_start;
+ part->part_size = part_size;
+ part->blocksize = part_blocksize;
- /* Tack this entry onto the list */
- part->next = *list;
- *list = part;
+ /* Tack this entry onto the list */
+ part->next = *list;
+ *list = part;
}
/* Note, we rely on partitions being dev-block-size aligned,
partition_mac_lookup( const char *dev_name, prom_handle disk,
unsigned int prom_blksize, struct partition_t** list )
{
- int block, map_size;
+ int block, map_size;
- /* block_buffer contains block 0 from the partitions_lookup() stage */
- struct mac_partition* part = (struct mac_partition *)block_buffer;
- unsigned short ptable_block_size =
- ((struct mac_driver_desc *)block_buffer)->block_size;
+ /* block_buffer contains block 0 from the partitions_lookup() stage */
+ struct mac_partition* part = (struct mac_partition *)block_buffer;
+ unsigned short ptable_block_size =
+ ((struct mac_driver_desc *)block_buffer)->block_size;
- map_size = 1;
- for (block=1; block < map_size + 1; block++)
- {
+ map_size = 1;
+ for (block=1; block < map_size + 1; block++)
+ {
#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
- int valid = 0;
- const char *ptype;
+ int valid = 0;
+ const char *ptype;
#endif
- if (prom_readblocks(disk, block, 1, block_buffer) != 1) {
- prom_printf("Can't read partition %d\n", block);
- break;
- }
- if (part->signature != MAC_PARTITION_MAGIC) {
+ if (prom_readblocks(disk, block, 1, block_buffer) != 1) {
+ prom_printf("Can't read partition %d\n", block);
+ break;
+ }
+ if (part->signature != MAC_PARTITION_MAGIC) {
#if 0
- prom_printf("Wrong partition %d signature\n", block);
+ prom_printf("Wrong partition %d signature\n", block);
#endif
- break;
- }
- if (block == 1)
- map_size = part->map_count;
+ break;
+ }
+ if (block == 1)
+ map_size = part->map_count;
#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
- /* We don't bother looking at swap partitions of any type,
- * and the rest are the ones we know about */
- for (ptype = valid_mac_partition_types; ptype; ptype++)
- if (!strcmp (part->type, ptype))
- {
- valid = 1;
- break;
- }
+ /* We don't bother looking at swap partitions of any type,
+ * and the rest are the ones we know about */
+ for (ptype = valid_mac_partition_types; ptype; ptype++)
+ if (!strcmp (part->type, ptype))
+ {
+ valid = 1;
+ break;
+ }
#if DEBUG
- if (!valid)
- prom_printf( "MAC: Unsupported partition #%d; type=%s\n",
- block, part->type );
+ if (!valid)
+ prom_printf( "MAC: Unsupported partition #%d; type=%s\n",
+ block, part->type );
#endif
#endif
#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
- if (valid)
+ if (valid)
#endif
- /* We use the partition block size from the partition table.
- * The filesystem implmentations are responsible for mapping
- * to their own fs blocksize */
- add_new_partition(
- list, /* partition list */
- block, /* partition number */
- part->type, /* type */
- part->name, /* name */
- part->start_block + part->data_start, /* start */
- part->data_count, /* size */
- ptable_block_size );
- }
+ /* We use the partition block size from the partition table.
+ * The filesystem implmentations are responsible for mapping
+ * to their own fs blocksize */
+ add_new_partition(
+ list, /* partition list */
+ block, /* partition number */
+ part->type, /* type */
+ part->name, /* name */
+ part->start_block + part->data_start, /* start */
+ part->data_count, /* size */
+ ptable_block_size );
+ }
}
/*
partition_fdisk_lookup( const char *dev_name, prom_handle disk,
unsigned int prom_blksize, struct partition_t** list )
{
- int partition;
+ int partition;
- /* fdisk partition tables start at offset 0x1be
- * from byte 0 of the boot drive.
- */
- struct fdisk_partition* part =
+ /* fdisk partition tables start at offset 0x1be
+ * from byte 0 of the boot drive.
+ */
+ struct fdisk_partition* part =
(struct fdisk_partition *) (block_buffer + 0x1be);
- for (partition=1; partition <= 4 ;partition++, part++) {
- if (part->sys_ind == LINUX_NATIVE) {
- add_new_partition( list,
- partition,
- "Linux", /* type */
- '\0', /* name */
- swab32(*(unsigned int *)(part->start4)),
- swab32(*(unsigned int *)(part->size4)),
- 512 /*blksize*/ );
- }
- }
+ for (partition=1; partition <= 4 ;partition++, part++) {
+ if (part->sys_ind == LINUX_NATIVE) {
+ add_new_partition( list,
+ partition,
+ "Linux", /* type */
+ '\0', /* name */
+ swab32(*(unsigned int *)(part->start4)),
+ swab32(*(unsigned int *)(part->size4)),
+ 512 /*blksize*/ );
+ }
+ }
}
/* I don't know if it's possible to handle multisession and other multitrack
static int
identify_iso_fs(ihandle device, unsigned int *iso_root_block)
{
- int block;
+ int block;
- for (block = 16; block < 100; block++) {
- struct iso_volume_descriptor * vdp;
+ for (block = 16; block < 100; block++) {
+ struct iso_volume_descriptor * vdp;
- if (prom_readblocks(device, block, 1, block_buffer) != 1) {
- prom_printf("Can't read volume desc block %d\n", block);
- break;
- }
+ if (prom_readblocks(device, block, 1, block_buffer) != 1) {
+ prom_printf("Can't read volume desc block %d\n", block);
+ break;
+ }
- vdp = (struct iso_volume_descriptor *)block_buffer;
+ vdp = (struct iso_volume_descriptor *)block_buffer;
- /* Due to the overlapping physical location of the descriptors,
- * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure
- * proper identification in this case, we first check for ISO.
- */
- if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
- *iso_root_block = block;
- return 1;
- }
- }
+ /* Due to the overlapping physical location of the descriptors,
+ * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure
+ * proper identification in this case, we first check for ISO.
+ */
+ if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
+ *iso_root_block = block;
+ return 1;
+ }
+ }
- return 0;
+ return 0;
}
struct partition_t*
partitions_lookup(const char *device)
{
- ihandle disk;
- struct mac_driver_desc *desc = (struct mac_driver_desc *)block_buffer;
- struct partition_t* list = NULL;
- unsigned int prom_blksize, iso_root_block;
+ ihandle disk;
+ struct mac_driver_desc *desc = (struct mac_driver_desc *)block_buffer;
+ struct partition_t* list = NULL;
+ unsigned int prom_blksize, iso_root_block;
- strncpy(block_buffer, device, 2040);
- strcat(block_buffer, ":0");
+ strncpy(block_buffer, device, 2040);
+ strcat(block_buffer, ":0");
- /* Open device */
- disk = prom_open(block_buffer);
- if (disk == NULL) {
- prom_printf("Can't open device <%s>\n", block_buffer);
- goto bail;
- }
- prom_blksize = prom_getblksize(disk);
- DEBUG_F("block size of device is %d\n", prom_blksize);
+ /* Open device */
+ disk = prom_open(block_buffer);
+ if (disk == NULL) {
+ prom_printf("Can't open device <%s>\n", block_buffer);
+ goto bail;
+ }
+ prom_blksize = prom_getblksize(disk);
+ DEBUG_F("block size of device is %d\n", prom_blksize);
- if (prom_blksize <= 1)
- prom_blksize = 512;
- if (prom_blksize > MAX_BLOCK_SIZE) {
- prom_printf("block_size %d not supported !\n", prom_blksize);
- goto bail;
- }
+ if (prom_blksize <= 1)
+ prom_blksize = 512;
+ if (prom_blksize > MAX_BLOCK_SIZE) {
+ prom_printf("block_size %d not supported !\n", prom_blksize);
+ goto bail;
+ }
- /* Read boot blocs */
- if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
- prom_printf("Can't read boot blocks\n");
- goto bail;
- }
- if (desc->signature == MAC_DRIVER_MAGIC) {
- /* pdisk partition format */
- partition_mac_lookup(device, disk, prom_blksize, &list);
- } else if ((block_buffer[510] == 0x55) && (block_buffer[511] == 0xaa)) {
- /* fdisk partition format */
- partition_fdisk_lookup(device, disk, prom_blksize, &list);
- } else if (prom_blksize == 2048 && identify_iso_fs(disk, &iso_root_block)) {
- add_new_partition(&list,
- 0,
- '\0',
- '\0',
- iso_root_block,
- 0,
- prom_blksize);
- prom_printf("ISO9660 disk\n");
- } else {
- prom_printf("No supported partition table detected\n");
- goto bail;
- }
+ /* Read boot blocs */
+ if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
+ prom_printf("Can't read boot blocks\n");
+ goto bail;
+ }
+ if (desc->signature == MAC_DRIVER_MAGIC) {
+ /* pdisk partition format */
+ partition_mac_lookup(device, disk, prom_blksize, &list);
+ } else if ((block_buffer[510] == 0x55) && (block_buffer[511] == 0xaa)) {
+ /* fdisk partition format */
+ partition_fdisk_lookup(device, disk, prom_blksize, &list);
+ } else if (prom_blksize == 2048 && identify_iso_fs(disk, &iso_root_block)) {
+ add_new_partition(&list,
+ 0,
+ '\0',
+ '\0',
+ iso_root_block,
+ 0,
+ prom_blksize);
+ prom_printf("ISO9660 disk\n");
+ } else {
+ prom_printf("No supported partition table detected\n");
+ goto bail;
+ }
bail:
- prom_close(disk);
+ prom_close(disk);
- return list;
+ return list;
}
char *
void
partitions_free(struct partition_t* list)
{
- struct partition_t* next;
+ struct partition_t* next;
- while(list) {
- next = list->next;
- free(list);
- list = next;
- }
+ while(list) {
+ next = list->next;
+ free(list);
+ list = next;
+ }
}
unsigned long
swab32(unsigned long value)
{
- __u32 result;
+ __u32 result;
- __asm__("rlwimi %0,%1,24,16,23\n\t"
- "rlwimi %0,%1,8,8,15\n\t"
- "rlwimi %0,%1,24,0,7"
- : "=r" (result)
- : "r" (value), "0" (value >> 24));
- return result;
+ __asm__("rlwimi %0,%1,24,16,23\n\t"
+ "rlwimi %0,%1,8,8,15\n\t"
+ "rlwimi %0,%1,24,0,7"
+ : "=r" (result)
+ : "r" (value), "0" (value >> 24));
+ return result;
}
#include "ctype.h"
#include "asm/processor.h"
#include "errors.h"
+#include "debug.h"
#define READ_BLOCKS_USE_READ 1
static ihandle prom_chosen, prom_options;
struct prom_args {
- const char *service;
- int nargs;
- int nret;
- void *args[10];
+ const char *service;
+ int nargs;
+ int nret;
+ void *args[10];
};
void *
call_prom (const char *service, int nargs, int nret, ...)
{
- va_list list;
- int i;
- struct prom_args prom_args;
+ va_list list;
+ int i;
+ struct prom_args prom_args;
- prom_args.service = service;
- prom_args.nargs = nargs;
- prom_args.nret = nret;
- va_start (list, nret);
- for (i = 0; i < nargs; ++i)
- prom_args.args[i] = va_arg(list, void *);
- va_end(list);
- for (i = 0; i < nret; ++i)
- prom_args.args[i + nargs] = 0;
- prom (&prom_args);
- if (nret > 0)
- return prom_args.args[nargs];
- else
- return 0;
+ prom_args.service = service;
+ prom_args.nargs = nargs;
+ prom_args.nret = nret;
+ va_start (list, nret);
+ for (i = 0; i < nargs; ++i)
+ prom_args.args[i] = va_arg(list, void *);
+ va_end(list);
+ for (i = 0; i < nret; ++i)
+ prom_args.args[i + nargs] = 0;
+ prom (&prom_args);
+ if (nret > 0)
+ return prom_args.args[nargs];
+ else
+ return 0;
}
void *
call_prom_return (const char *service, int nargs, int nret, ...)
{
- va_list list;
- int i;
- void* result;
- struct prom_args prom_args;
+ va_list list;
+ int i;
+ void* result;
+ struct prom_args prom_args;
- prom_args.service = service;
- prom_args.nargs = nargs;
- prom_args.nret = nret;
- va_start (list, nret);
- for (i = 0; i < nargs; ++i)
- prom_args.args[i] = va_arg(list, void *);
- for (i = 0; i < nret; ++i)
- prom_args.args[i + nargs] = 0;
- if (prom (&prom_args) != 0)
- return PROM_INVALID_HANDLE;
- if (nret > 0) {
- result = prom_args.args[nargs];
- for (i=1; i<nret; i++) {
- void** rp = va_arg(list, void**);
- *rp = prom_args.args[i+nargs];
- }
- } else
- result = 0;
- va_end(list);
- return result;
+ prom_args.service = service;
+ prom_args.nargs = nargs;
+ prom_args.nret = nret;
+ va_start (list, nret);
+ for (i = 0; i < nargs; ++i)
+ prom_args.args[i] = va_arg(list, void *);
+ for (i = 0; i < nret; ++i)
+ prom_args.args[i + nargs] = 0;
+ if (prom (&prom_args) != 0)
+ return PROM_INVALID_HANDLE;
+ if (nret > 0) {
+ result = prom_args.args[nargs];
+ for (i=1; i<nret; i++) {
+ void** rp = va_arg(list, void**);
+ *rp = prom_args.args[i+nargs];
+ }
+ } else
+ result = 0;
+ va_end(list);
+ return result;
}
static void *
call_method_1 (char *method, prom_handle h, int nargs, ...)
{
- va_list list;
- int i;
- struct prom_args prom_args;
+ va_list list;
+ int i;
+ struct prom_args prom_args;
- prom_args.service = "call-method";
- prom_args.nargs = nargs+2;
- prom_args.nret = 2;
- prom_args.args[0] = method;
- prom_args.args[1] = h;
- va_start (list, nargs);
- for (i = 0; i < nargs; ++i)
- prom_args.args[2+i] = va_arg(list, void *);
- va_end(list);
- prom_args.args[2+nargs] = 0;
- prom_args.args[2+nargs+1] = 0;
+ prom_args.service = "call-method";
+ prom_args.nargs = nargs+2;
+ prom_args.nret = 2;
+ prom_args.args[0] = method;
+ prom_args.args[1] = h;
+ va_start (list, nargs);
+ for (i = 0; i < nargs; ++i)
+ prom_args.args[2+i] = va_arg(list, void *);
+ va_end(list);
+ prom_args.args[2+nargs] = 0;
+ prom_args.args[2+nargs+1] = 0;
- prom (&prom_args);
+ prom (&prom_args);
- if (prom_args.args[2+nargs] != 0)
- {
- prom_printf ("method '%s' failed %p\n", method, prom_args.args[2+nargs]);
- return 0;
- }
- return prom_args.args[2+nargs+1];
+ if (prom_args.args[2+nargs] != 0)
+ {
+ prom_printf ("method '%s' failed %p\n", method, prom_args.args[2+nargs]);
+ return 0;
+ }
+ return prom_args.args[2+nargs+1];
}
prom_handle
prom_finddevice (char *name)
{
- return call_prom ("finddevice", 1, 1, name);
+ return call_prom ("finddevice", 1, 1, name);
}
prom_handle
prom_findpackage(char *path)
{
- return call_prom ("find-package", 1, 1, path);
+ return call_prom ("find-package", 1, 1, path);
}
int
prom_getprop (prom_handle pack, char *name, void *mem, int len)
{
- return (int)call_prom ("getprop", 4, 1, pack, name, mem, len);
+ return (int)call_prom ("getprop", 4, 1, pack, name, mem, len);
}
int
prom_get_chosen (char *name, void *mem, int len)
{
- return prom_getprop (prom_chosen, name, mem, len);
+ return prom_getprop (prom_chosen, name, mem, len);
}
int
prom_get_options (char *name, void *mem, int len)
{
- if (prom_options == (void *)-1)
- return -1;
- return prom_getprop (prom_options, name, mem, len);
+ if (prom_options == (void *)-1)
+ return -1;
+ return prom_getprop (prom_options, name, mem, len);
}
int
void
prom_init (prom_entry pp)
{
- prom = pp;
-
- prom_chosen = prom_finddevice ("/chosen");
- if (prom_chosen == (void *)-1)
- prom_exit ();
- prom_options = prom_finddevice ("/options");
- if (prom_get_chosen ("stdout", &prom_stdout, sizeof(prom_stdout)) <= 0)
- prom_exit();
- if (prom_get_chosen ("stdin", &prom_stdin, sizeof(prom_stdin)) <= 0)
- prom_abort ("\nCan't open stdin");
- if (prom_get_chosen ("memory", &prom_mem, sizeof(prom_mem)) <= 0)
- prom_abort ("\nCan't get mem handle");
- if (prom_get_chosen ("mmu", &prom_mmu, sizeof(prom_mmu)) <= 0)
- prom_abort ("\nCan't get mmu handle");
+ prom = pp;
+
+ prom_chosen = prom_finddevice ("/chosen");
+ if (prom_chosen == (void *)-1)
+ prom_exit ();
+ prom_options = prom_finddevice ("/options");
+ if (prom_get_chosen ("stdout", &prom_stdout, sizeof(prom_stdout)) <= 0)
+ prom_exit();
+ if (prom_get_chosen ("stdin", &prom_stdin, sizeof(prom_stdin)) <= 0)
+ prom_abort ("\nCan't open stdin");
+ if (prom_get_chosen ("memory", &prom_mem, sizeof(prom_mem)) <= 0)
+ prom_abort ("\nCan't get mem handle");
+ if (prom_get_chosen ("mmu", &prom_mmu, sizeof(prom_mmu)) <= 0)
+ prom_abort ("\nCan't get mmu handle");
// move cursor to fresh line
- prom_printf ("\n");
+ prom_printf ("\n");
- /* Add a few OF methods (thanks Darwin) */
+ /* Add a few OF methods (thanks Darwin) */
#if DEBUG
- prom_printf ("Adding OF methods...\n");
+ prom_printf ("Adding OF methods...\n");
#endif
- prom_interpret (
- /* All values in this forth code are in hex */
- "hex "
- /* Those are a few utilities ripped from Apple */
- ": D2NIP decode-int nip nip ;\r" // A useful function to save space
- ": GPP$ get-package-property 0= ;\r" // Another useful function to save space
- ": ^on0 0= if -1 throw then ;\r" // Bail if result zero
- ": $CM $call-method ;\r"
- );
-
- /* Some forth words used by the release method */
- prom_interpret (
- " \" /chosen\" find-package if "
- "dup \" memory\" rot GPP$ if "
- "D2NIP swap " // ( MEMORY-ihandle "/chosen"-phandle )
- "\" mmu\" rot GPP$ if "
- "D2NIP " // ( MEMORY-ihandle MMU-ihandle )
- "else "
- "0 " // ( MEMORY-ihandle 0 )
- "then "
- "else "
- "0 0 " // ( 0 0 )
- "then "
- "else "
- "0 0 " // ( 0 0 )
- "then\r"
- "value mmu# "
- "value mem# "
- );
-
- prom_interpret (
- ": ^mem mem# $CM ; "
- ": ^mmu mmu# $CM ; "
- );
-
-#if DEBUG
- prom_printf ("OF interface initialized.\n");
-#endif
+ prom_interpret (
+ /* All values in this forth code are in hex */
+ "hex "
+ /* Those are a few utilities ripped from Apple */
+ ": D2NIP decode-int nip nip ;\r" // A useful function to save space
+ ": GPP$ get-package-property 0= ;\r" // Another useful function to save space
+ ": ^on0 0= if -1 throw then ;\r" // Bail if result zero
+ ": $CM $call-method ;\r"
+ );
+
+ /* Some forth words used by the release method */
+ prom_interpret (
+ " \" /chosen\" find-package if "
+ "dup \" memory\" rot GPP$ if "
+ "D2NIP swap " // ( MEMORY-ihandle "/chosen"-phandle )
+ "\" mmu\" rot GPP$ if "
+ "D2NIP " // ( MEMORY-ihandle MMU-ihandle )
+ "else "
+ "0 " // ( MEMORY-ihandle 0 )
+ "then "
+ "else "
+ "0 0 " // ( 0 0 )
+ "then "
+ "else "
+ "0 0 " // ( 0 0 )
+ "then\r"
+ "value mmu# "
+ "value mem# "
+ );
+
+ prom_interpret (
+ ": ^mem mem# $CM ; "
+ ": ^mmu mmu# $CM ; "
+ );
+
+ DEBUG_F("OF interface initialized.\n");
}
prom_handle
prom_open (char *spec)
{
- return call_prom ("open", 1, 1, spec, strlen(spec));
+ return call_prom ("open", 1, 1, spec, strlen(spec));
}
void
prom_close (prom_handle file)
{
- call_prom ("close", 1, 0, file);
+ call_prom ("close", 1, 0, file);
}
int
prom_read (prom_handle file, void *buf, int n)
{
- int result = 0;
- int retries = 10;
+ int result = 0;
+ int retries = 10;
- if (n == 0)
- return 0;
- while(--retries) {
- result = (int)call_prom ("read", 3, 1, file, buf, n);
- if (result != 0)
- break;
- call_prom("interpret", 1, 1, " 10 ms");
- }
+ if (n == 0)
+ return 0;
+ while(--retries) {
+ result = (int)call_prom ("read", 3, 1, file, buf, n);
+ if (result != 0)
+ break;
+ call_prom("interpret", 1, 1, " 10 ms");
+ }
- return result;
+ return result;
}
int
prom_write (prom_handle file, void *buf, int n)
{
- return (int)call_prom ("write", 3, 1, file, buf, n);
+ return (int)call_prom ("write", 3, 1, file, buf, n);
}
int
prom_seek (prom_handle file, int pos)
{
- int status = (int)call_prom ("seek", 3, 1, file, 0, pos);
- return status == 0 || status == 1;
+ int status = (int)call_prom ("seek", 3, 1, file, 0, pos);
+ return status == 0 || status == 1;
}
int
prom_lseek (prom_handle file, unsigned long long pos)
{
- int status = (int)call_prom ("seek", 3, 1, file,
- (unsigned int)(pos >> 32), (unsigned int)(pos & 0xffffffffUL));
- return status == 0 || status == 1;
+ int status = (int)call_prom ("seek", 3, 1, file,
+ (unsigned int)(pos >> 32), (unsigned int)(pos & 0xffffffffUL));
+ return status == 0 || status == 1;
}
int
prom_loadmethod (prom_handle device, void* addr)
{
- return (int)call_method_1 ("load", device, 1, addr);
+ return (int)call_method_1 ("load", device, 1, addr);
}
int
prom_getblksize (prom_handle file)
{
- return (int)call_method_1 ("block-size", file, 0);
+ return (int)call_method_1 ("block-size", file, 0);
}
int
prom_readblocks (prom_handle dev, int blockNum, int blockCount, void *buffer)
{
#if READ_BLOCKS_USE_READ
- int status;
- unsigned int blksize;
+ int status;
+ unsigned int blksize;
- blksize = prom_getblksize(dev);
- if (blksize <= 1)
- blksize = 512;
- status = prom_seek(dev, blockNum * blksize);
- if (status != 1) {
- return 0;
- prom_printf("Can't seek to 0x%x\n", blockNum * blksize);
- }
+ blksize = prom_getblksize(dev);
+ if (blksize <= 1)
+ blksize = 512;
+ status = prom_seek(dev, blockNum * blksize);
+ if (status != 1) {
+ return 0;
+ prom_printf("Can't seek to 0x%x\n", blockNum * blksize);
+ }
- status = prom_read(dev, buffer, blockCount * blksize);
+ status = prom_read(dev, buffer, blockCount * blksize);
// prom_printf("prom_readblocks, bl: %d, cnt: %d, status: %d\n",
// blockNum, blockCount, status);
- return status == (blockCount * blksize);
+ return status == (blockCount * blksize);
#else
- int result;
- int retries = 10;
+ int result;
+ int retries = 10;
- if (blockCount == 0)
- return blockCount;
- while(--retries) {
- result = call_method_1 ("read-blocks", dev, 3, buffer, blockNum, blockCount);
- if (result != 0)
- break;
- call_prom("interpret", 1, 1, " 10 ms");
- }
+ if (blockCount == 0)
+ return blockCount;
+ while(--retries) {
+ result = call_method_1 ("read-blocks", dev, 3, buffer, blockNum, blockCount);
+ if (result != 0)
+ break;
+ call_prom("interpret", 1, 1, " 10 ms");
+ }
- return result;
+ return result;
#endif
}
int
prom_getchar ()
{
- char c[4];
- int a;
+ char c[4];
+ int a;
- while ((a = (int)call_prom ("read", 3, 1, prom_stdin, c, 4)) == 0)
- ;
- if (a == -1)
- prom_abort ("EOF on console\n");
- if (a == 3 && c[0] == '\e' && c[1] == '[')
- return 0x100 | c[2];
- return c[0];
+ while ((a = (int)call_prom ("read", 3, 1, prom_stdin, c, 4)) == 0)
+ ;
+ if (a == -1)
+ prom_abort ("EOF on console\n");
+ if (a == 3 && c[0] == '\e' && c[1] == '[')
+ return 0x100 | c[2];
+ return c[0];
}
int
prom_nbgetchar()
{
- char ch;
+ char ch;
- return (int) call_prom("read", 3, 1, prom_stdin, &ch, 1) > 0? ch: -1;
+ return (int) call_prom("read", 3, 1, prom_stdin, &ch, 1) > 0? ch: -1;
}
void
prom_putchar (char c)
{
- if (c == '\n')
- call_prom ("write", 3, 1, prom_stdout, "\r\n", 2);
- else
- call_prom ("write", 3, 1, prom_stdout, &c, 1);
+ if (c == '\n')
+ call_prom ("write", 3, 1, prom_stdout, "\r\n", 2);
+ else
+ call_prom ("write", 3, 1, prom_stdout, &c, 1);
}
void
prom_puts (prom_handle file, char *s)
{
- const char *p, *q;
-
- for (p = s; *p != 0; p = q)
- {
- for (q = p; *q != 0 && *q != '\n'; ++q)
- ;
- if (q > p)
- call_prom ("write", 3, 1, file, p, q - p);
- if (*q != 0)
- {
- ++q;
- call_prom ("write", 3, 1, file, "\r\n", 2);
- }
- }
+ const char *p, *q;
+
+ for (p = s; *p != 0; p = q)
+ {
+ for (q = p; *q != 0 && *q != '\n'; ++q)
+ ;
+ if (q > p)
+ call_prom ("write", 3, 1, file, p, q - p);
+ if (*q != 0)
+ {
+ ++q;
+ call_prom ("write", 3, 1, file, "\r\n", 2);
+ }
+ }
}
void
prom_vfprintf (prom_handle file, char *fmt, va_list ap)
{
- static char printf_buf[1536];
- vsprintf (printf_buf, fmt, ap);
- prom_puts (file, printf_buf);
+ static char printf_buf[1536];
+ vsprintf (printf_buf, fmt, ap);
+ prom_puts (file, printf_buf);
}
void
prom_vprintf (char *fmt, va_list ap)
{
- static char printf_buf[1536];
- vsprintf (printf_buf, fmt, ap);
- prom_puts (prom_stdout, printf_buf);
+ static char printf_buf[1536];
+ vsprintf (printf_buf, fmt, ap);
+ prom_puts (prom_stdout, printf_buf);
}
void
prom_fprintf (prom_handle file, char *fmt, ...)
{
- va_list ap;
- va_start (ap, fmt);
- prom_vfprintf (file, fmt, ap);
- va_end (ap);
+ va_list ap;
+ va_start (ap, fmt);
+ prom_vfprintf (file, fmt, ap);
+ va_end (ap);
}
void
prom_printf (char *fmt, ...)
{
- va_list ap;
- va_start (ap, fmt);
- prom_vfprintf (prom_stdout, fmt, ap);
- va_end (ap);
+ va_list ap;
+ va_start (ap, fmt);
+ prom_vfprintf (prom_stdout, fmt, ap);
+ va_end (ap);
}
void
void
prom_readline (char *prompt, char *buf, int len)
{
- int i = 0;
- int c;
-
- if (prompt)
- prom_puts (prom_stdout, prompt);
-
- while (i < len-1 && (c = prom_getchar ()) != '\r')
- {
- if (c >= 0x100)
- continue;
- if (c == 8)
- {
- if (i > 0)
- {
- prom_puts (prom_stdout, "\b \b");
- i--;
- }
+ int i = 0;
+ int c;
+
+ if (prompt)
+ prom_puts (prom_stdout, prompt);
+
+ while (i < len-1 && (c = prom_getchar ()) != '\r')
+ {
+ if (c >= 0x100)
+ continue;
+ if (c == 8)
+ {
+ if (i > 0)
+ {
+ prom_puts (prom_stdout, "\b \b");
+ i--;
+ }
+ else
+ prom_putchar ('\a');
+ }
+ else if (isprint (c))
+ {
+ prom_putchar (c);
+ buf[i++] = c;
+ }
else
- prom_putchar ('\a');
- }
- else if (isprint (c))
- {
- prom_putchar (c);
- buf[i++] = c;
- }
- else
- prom_putchar ('\a');
- }
- prom_putchar ('\n');
- buf[i] = 0;
+ prom_putchar ('\a');
+ }
+ prom_putchar ('\n');
+ buf[i] = 0;
}
#ifdef CONFIG_SET_COLORMAP
int prom_set_color(prom_handle device, int color, int r, int g, int b)
{
- return (int)call_prom( "call-method", 6, 1, "color!", device, color, b, g, r );
+ return (int)call_prom( "call-method", 6, 1, "color!", device, color, b, g, r );
}
#endif /* CONFIG_SET_COLORMAP */
void
prom_exit ()
{
- call_prom ("exit", 0, 0);
+ call_prom ("exit", 0, 0);
}
void
prom_abort (char *fmt, ...)
{
- va_list ap;
- va_start (ap, fmt);
- prom_vfprintf (prom_stdout, fmt, ap);
- va_end (ap);
- prom_exit ();
+ va_list ap;
+ va_start (ap, fmt);
+ prom_vfprintf (prom_stdout, fmt, ap);
+ va_end (ap);
+ prom_exit ();
}
void
void *
prom_claim (void *virt, unsigned int size, unsigned int align)
{
- return call_prom ("claim", 3, 1, virt, size, align);
+ return call_prom ("claim", 3, 1, virt, size, align);
}
void
prom_release(void *virt, unsigned int size)
{
// call_prom ("release", 2, 1, virt, size);
- /* release in not enough, it needs also an unmap call. This bit of forth
- * code inspired from Darwin's bootloader but could be replaced by direct
- * calls to the MMU package if needed
- */
- call_prom ("interpret", 3, 1,
+ /* release in not enough, it needs also an unmap call. This bit of forth
+ * code inspired from Darwin's bootloader but could be replaced by direct
+ * calls to the MMU package if needed
+ */
+ call_prom ("interpret", 3, 1,
#if DEBUG
".\" ReleaseMem:\" 2dup . . cr "
#endif
"2dup \" release\" ^mmu " // Then free the virtual pages
"\" release\" ^mem " // Then free the physical pages
,size, virt
- );
+ );
}
void
prom_map (void *phys, void *virt, int size)
{
- unsigned long msr = mfmsr();
+ unsigned long msr = mfmsr();
- /* Only create a mapping if we're running with relocation enabled. */
- if ( (msr & MSR_IR) && (msr & MSR_DR) )
- call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys);
+ /* Only create a mapping if we're running with relocation enabled. */
+ if ( (msr & MSR_IR) && (msr & MSR_DR) )
+ call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys);
}
void
prom_unmap (void *phys, void *virt, int size)
{
- unsigned long msr = mfmsr();
+ unsigned long msr = mfmsr();
- /* Only unmap if we're running with relocation enabled. */
- if ( (msr & MSR_IR) && (msr & MSR_DR) )
- call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys);
+ /* Only unmap if we're running with relocation enabled. */
+ if ( (msr & MSR_IR) && (msr & MSR_DR) )
+ call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys);
}
char *
prom_getargs ()
{
- static char args[256];
- int l;
+ static char args[256];
+ int l;
- l = prom_get_chosen ("bootargs", args, 255);
- args[l] = '\0';
- return args;
+ l = prom_get_chosen ("bootargs", args, 255);
+ args[l] = '\0';
+ return args;
}
void
prom_setargs (char *args)
{
- int l = strlen (args)+1;
- if ((int)call_prom ("setprop", 4, 1, prom_chosen, "bootargs", args, l) != l)
- prom_printf ("can't set args\n");
+ int l = strlen (args)+1;
+ if ((int)call_prom ("setprop", 4, 1, prom_chosen, "bootargs", args, l) != l)
+ prom_printf ("can't set args\n");
}
int prom_interpret (char *forth)
{
- return (int)call_prom("interpret", 1, 1, forth);
+ return (int)call_prom("interpret", 1, 1, forth);
}
int
prom_getms(void)
{
- return (int) call_prom("milliseconds", 0, 1);
+ return (int) call_prom("milliseconds", 0, 1);
}
void
prom_pause(void)
{
- call_prom("enter", 0, 0);
+ call_prom("enter", 0, 0);
}
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
#define KERNEL_LINK_ADDR_PPC64 0xC000000000000000ULL
typedef struct {
- union {
- Elf32_Ehdr elf32hdr;
- Elf64_Ehdr elf64hdr;
- } elf;
- void* base;
- unsigned long memsize;
- unsigned long filesize;
- unsigned long offset;
- unsigned long load_loc;
- unsigned long entry;
+ union {
+ Elf32_Ehdr elf32hdr;
+ Elf64_Ehdr elf64hdr;
+ } elf;
+ void* base;
+ unsigned long memsize;
+ unsigned long filesize;
+ unsigned long offset;
+ unsigned long load_loc;
+ unsigned long entry;
} loadinfo_t;
typedef void (*kernel_entry_t)( void *,
/* Color values for text ui */
static struct ansi_color_t {
- char* name;
- int index;
- int value;
+ char* name;
+ int index;
+ int value;
} ansi_color_table[] = {
- { "black", 2, 30 },
- { "blue", 0, 31 },
- { "green", 0, 32 },
- { "cyan", 0, 33 },
- { "red", 0, 34 },
- { "purple", 0, 35 },
- { "brown", 0, 36 },
- { "light-gray", 0, 37 },
- { "dark-gray", 1, 30 },
- { "light-blue", 1, 31 },
- { "light-green", 1, 32 },
- { "light-cyan", 1, 33 },
- { "light-red", 1, 34 },
- { "light-purple", 1, 35 },
- { "yellow", 1, 36 },
- { "white", 1, 37 },
- { NULL, 0, 0 },
+ { "black", 2, 30 },
+ { "blue", 0, 31 },
+ { "green", 0, 32 },
+ { "cyan", 0, 33 },
+ { "red", 0, 34 },
+ { "purple", 0, 35 },
+ { "brown", 0, 36 },
+ { "light-gray", 0, 37 },
+ { "dark-gray", 1, 30 },
+ { "light-blue", 1, 31 },
+ { "light-green", 1, 32 },
+ { "light-cyan", 1, 33 },
+ { "light-red", 1, 34 },
+ { "light-purple", 1, 35 },
+ { "yellow", 1, 36 },
+ { "white", 1, 37 },
+ { NULL, 0, 0 },
};
/* Default colors for text ui */
int
yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
{
- int result;
- void* malloc_base = NULL;
- prom_handle root;
+ int result;
+ void* malloc_base = NULL;
+ prom_handle root;
- /* OF seems to do it, but I'm not very confident */
- memset(&__bss_start, 0, &_end - &__bss_start);
+ /* OF seems to do it, but I'm not very confident */
+ memset(&__bss_start, 0, &_end - &__bss_start);
- /* Check for quik first stage bootloader (but I don't think we are
- * compatible with it anyway, I'll look into backporting to older OF
- * versions later
- */
- if (r5 == 0xdeadbeef) {
- r5 = r3;
- quik_fip = (struct first_info *)r4;
- }
-
- /* Initialize OF interface */
- prom_init ((prom_entry) r5);
+ /* Check for quik first stage bootloader (but I don't think we are
+ * compatible with it anyway, I'll look into backporting to older OF
+ * versions later
+ */
+ if (r5 == 0xdeadbeef) {
+ r5 = r3;
+ quik_fip = (struct first_info *)r4;
+ }
+
+ /* Initialize OF interface */
+ prom_init ((prom_entry) r5);
- /* Allocate some memory for malloc'ator */
- malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0);
- if (malloc_base == (void *)-1) {
- prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n",
- MALLOCSIZE, MALLOCADDR);
- return -1;
- }
- malloc_init(malloc_base, MALLOCSIZE);
- DEBUG_F("Malloc buffer allocated at %p (%d bytes)\n",
- malloc_base, MALLOCSIZE);
+ /* Allocate some memory for malloc'ator */
+ malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0);
+ if (malloc_base == (void *)-1) {
+ prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n",
+ MALLOCSIZE, MALLOCADDR);
+ return -1;
+ }
+ malloc_init(malloc_base, MALLOCSIZE);
+ DEBUG_F("Malloc buffer allocated at %p (%d bytes)\n",
+ malloc_base, MALLOCSIZE);
- /* A few useless DEBUG_F's */
- DEBUG_F("reloc_offset : %ld (should be 0)\n", reloc_offset());
- DEBUG_F("test_bss : %d (should be 0)\n", test_bss);
- DEBUG_F("test_data : %d (should be 0)\n", test_data);
- DEBUG_F("&test_data : %p\n", &test_data);
- DEBUG_F("&test_bss : %p\n", &test_bss);
- DEBUG_F("linked at : 0x%08x\n", TEXTADDR);
-
- /* ask the OF info if we're a chrp or pmac */
- /* we need to set _machine before calling finish_device_tree */
- root = prom_finddevice("/");
- if (root != 0) {
- static char model[256];
- if (prom_getprop(root, "device_type", model, 256 ) > 0 &&
- !strncmp("chrp", model, 4))
- _machine = _MACH_chrp;
- else {
- if (prom_getprop(root, "model", model, 256 ) > 0 &&
- !strncmp(model, "IBM", 3))
- _machine = _MACH_chrp;
- }
- }
+ /* A few useless DEBUG_F's */
+ DEBUG_F("reloc_offset : %ld (should be 0)\n", reloc_offset());
+ DEBUG_F("test_bss : %d (should be 0)\n", test_bss);
+ DEBUG_F("test_data : %d (should be 0)\n", test_data);
+ DEBUG_F("&test_data : %p\n", &test_data);
+ DEBUG_F("&test_bss : %p\n", &test_bss);
+ DEBUG_F("linked at : 0x%08x\n", TEXTADDR);
+
+ /* ask the OF info if we're a chrp or pmac */
+ /* we need to set _machine before calling finish_device_tree */
+ root = prom_finddevice("/");
+ if (root != 0) {
+ static char model[256];
+ if (prom_getprop(root, "device_type", model, 256 ) > 0 &&
+ !strncmp("chrp", model, 4))
+ _machine = _MACH_chrp;
+ else {
+ if (prom_getprop(root, "model", model, 256 ) > 0 &&
+ !strncmp(model, "IBM", 3))
+ _machine = _MACH_chrp;
+ }
+ }
- DEBUG_F("Running on _machine = %d\n", _machine);
- DEBUG_SLEEP;
+ DEBUG_F("Running on _machine = %d\n", _machine);
+ DEBUG_SLEEP;
- /* Call out main */
- result = yaboot_main();
+ /* Call out main */
+ result = yaboot_main();
- /* Get rid of malloc pool */
- malloc_dispose();
- prom_release(malloc_base, MALLOCSIZE);
- DEBUG_F("Malloc buffer released. Exiting with code %d\n",
- result);
+ /* Get rid of malloc pool */
+ malloc_dispose();
+ prom_release(malloc_base, MALLOCSIZE);
+ DEBUG_F("Malloc buffer released. Exiting with code %d\n",
+ result);
- /* Return to OF */
- prom_exit();
+ /* Return to OF */
+ prom_exit();
- return result;
+ return result;
}
static int
check_color_text_ui(char *color)
{
- int i = 0;
- while(ansi_color_table[i].name) {
- if (!strcmp(color, ansi_color_table[i].name))
- return i;
- i++;
- }
- return -1;
+ int i = 0;
+ while(ansi_color_table[i].name) {
+ if (!strcmp(color, ansi_color_table[i].name))
+ return i;
+ i++;
+ }
+ return -1;
}
#endif /* CONFIG_COLOR_TEXT */
static int
load_config_file(char *device, char* path, int partition)
{
- char *conf_file = NULL, *p;
- struct boot_file_t file;
- int sz, opened = 0, result = 0;
- char conf_path[512];
- struct boot_fspec_t fspec;
-
- /* Allocate a buffer for the config file */
- conf_file = malloc(CONFIG_FILE_MAX);
- if (!conf_file) {
- prom_printf("Can't alloc config file buffer\n");
- goto bail;
- }
-
- /* Build the path to the file */
- if (path)
- strcpy(conf_path, path);
- else if ( _machine == _MACH_chrp )
- strcpy(conf_path, "/etc/");
- else
- conf_path[0] = 0;
- strcat(conf_path, CONFIG_FILE_NAME);
-
- /* Open it */
- fspec.dev = device;
- fspec.file = conf_path;
- fspec.part = partition;
- result = open_file(&fspec, &file);
- if (result != FILE_ERR_OK) {
- prom_printf("%s:%d,", fspec.dev, fspec.part);
- prom_perror(result, fspec.file);
- prom_printf("Can't open config file\n");
- goto bail;
- }
- opened = 1;
-
- /* Read it */
- sz = file.fs->read(&file, CONFIG_FILE_MAX, conf_file);
- if (sz <= 0) {
- prom_printf("Error, can't read config file\n");
- goto bail;
- }
- prom_printf("Config file read, %d bytes\n", sz);
-
- /* Close the file */
- if (opened)
- file.fs->close(&file);
- opened = 0;
-
- /* Call the parsing code in cfg.c */
- if (cfg_parse(conf_path, conf_file, sz) < 0) {
- prom_printf ("Syntax error or read error config\n");
- goto bail;
- }
-
- DEBUG_F("Config file successfully parsed, %d bytes\n", sz);
-
- /* Now, we do the initialisations stored in the config file */
- p = cfg_get_strg(0, "init-code");
- if (p)
- prom_interpret(p);
-
- password = cfg_get_strg(0, "password");
+ char *conf_file = NULL, *p;
+ struct boot_file_t file;
+ int sz, opened = 0, result = 0;
+ char conf_path[512];
+ struct boot_fspec_t fspec;
+
+ /* Allocate a buffer for the config file */
+ conf_file = malloc(CONFIG_FILE_MAX);
+ if (!conf_file) {
+ prom_printf("Can't alloc config file buffer\n");
+ goto bail;
+ }
+
+ /* Build the path to the file */
+ if (path)
+ strcpy(conf_path, path);
+ else if ( _machine == _MACH_chrp )
+ strcpy(conf_path, "/etc/");
+ else
+ conf_path[0] = 0;
+ strcat(conf_path, CONFIG_FILE_NAME);
+
+ /* Open it */
+ fspec.dev = device;
+ fspec.file = conf_path;
+ fspec.part = partition;
+ result = open_file(&fspec, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("%s:%d,", fspec.dev, fspec.part);
+ prom_perror(result, fspec.file);
+ prom_printf("Can't open config file\n");
+ goto bail;
+ }
+ opened = 1;
+
+ /* Read it */
+ sz = file.fs->read(&file, CONFIG_FILE_MAX, conf_file);
+ if (sz <= 0) {
+ prom_printf("Error, can't read config file\n");
+ goto bail;
+ }
+ prom_printf("Config file read, %d bytes\n", sz);
+
+ /* Close the file */
+ if (opened)
+ file.fs->close(&file);
+ opened = 0;
+
+ /* Call the parsing code in cfg.c */
+ if (cfg_parse(conf_path, conf_file, sz) < 0) {
+ prom_printf ("Syntax error or read error config\n");
+ goto bail;
+ }
+
+ DEBUG_F("Config file successfully parsed, %d bytes\n", sz);
+
+ /* Now, we do the initialisations stored in the config file */
+ p = cfg_get_strg(0, "init-code");
+ if (p)
+ prom_interpret(p);
+
+ password = cfg_get_strg(0, "password");
#ifdef CONFIG_COLOR_TEXT
- p = cfg_get_strg(0, "fgcolor");
- if (p) {
- DEBUG_F("fgcolor=%s\n", p);
- fgcolor = check_color_text_ui(p);
- if (fgcolor == -1) {
- prom_printf("Invalid fgcolor: \"%s\".\n", p);
- }
- }
- p = cfg_get_strg(0, "bgcolor");
- if (p) {
- DEBUG_F("bgcolor=%s\n", p);
- bgcolor = check_color_text_ui(p);
- if (bgcolor == -1)
- prom_printf("Invalid bgcolor: \"%s\".\n", p);
- }
- if (bgcolor >= 0) {
- char temp[64];
- sprintf(temp, "%x to background-color", bgcolor);
- prom_interpret(temp);
+ p = cfg_get_strg(0, "fgcolor");
+ if (p) {
+ DEBUG_F("fgcolor=%s\n", p);
+ fgcolor = check_color_text_ui(p);
+ if (fgcolor == -1) {
+ prom_printf("Invalid fgcolor: \"%s\".\n", p);
+ }
+ }
+ p = cfg_get_strg(0, "bgcolor");
+ if (p) {
+ DEBUG_F("bgcolor=%s\n", p);
+ bgcolor = check_color_text_ui(p);
+ if (bgcolor == -1)
+ prom_printf("Invalid bgcolor: \"%s\".\n", p);
+ }
+ if (bgcolor >= 0) {
+ char temp[64];
+ sprintf(temp, "%x to background-color", bgcolor);
+ prom_interpret(temp);
#if !DEBUG
- prom_printf("\xc");
+ prom_printf("\xc");
#endif /* !DEBUG */
- }
- if (fgcolor >= 0) {
- char temp[64];
- sprintf(temp, "%x to foreground-color", fgcolor);
- prom_interpret(temp);
- }
+ }
+ if (fgcolor >= 0) {
+ char temp[64];
+ sprintf(temp, "%x to foreground-color", fgcolor);
+ prom_interpret(temp);
+ }
#endif /* CONFIG_COLOR_TEXT */
- p = cfg_get_strg(0, "init-message");
- if (p)
- prom_printf("%s\n", p);
+ p = cfg_get_strg(0, "init-message");
+ if (p)
+ prom_printf("%s\n", p);
#if 0
- p = cfg_get_strg(0, "message");
- if (p)
- print_message_file(p);
+ p = cfg_get_strg(0, "message");
+ if (p)
+ print_message_file(p);
#endif
- result = 1;
+ result = 1;
bail:
- if (opened)
- file.fs->close(&file);
+ if (opened)
+ file.fs->close(&file);
- if (result != 1 && conf_file)
- free(conf_file);
+ if (result != 1 && conf_file)
+ free(conf_file);
- return result;
+ return result;
}
void maintabfunc (void)
{
- if (useconf) {
- cfg_print_images();
- prom_printf("boot: %s", cbuff);
- }
+ if (useconf) {
+ cfg_print_images();
+ prom_printf("boot: %s", cbuff);
+ }
}
void
word_split(char **linep, char **paramsp)
{
- char *p;
-
- *paramsp = 0;
- p = *linep;
- if (p == 0)
- return;
- while (*p == ' ')
- ++p;
- if (*p == 0) {
- *linep = 0;
- return;
- }
- *linep = p;
- while (*p != 0 && *p != ' ')
- ++p;
- while (*p == ' ')
- *p++ = 0;
- if (*p != 0)
- *paramsp = p;
+ char *p;
+
+ *paramsp = 0;
+ p = *linep;
+ if (p == 0)
+ return;
+ while (*p == ' ')
+ ++p;
+ if (*p == 0) {
+ *linep = 0;
+ return;
+ }
+ *linep = p;
+ while (*p != 0 && *p != ' ')
+ ++p;
+ while (*p == ' ')
+ *p++ = 0;
+ if (*p != 0)
+ *paramsp = p;
}
char *
make_params(char *label, char *params)
{
- char *p, *q;
- static char buffer[2048];
-
- q = buffer;
- *q = 0;
-
- p = cfg_get_strg(label, "literal");
- if (p) {
- strcpy(q, p);
- q = strchr(q, 0);
- if (params) {
- if (*p)
- *q++ = ' ';
- strcpy(q, params);
- }
- return buffer;
- }
-
- p = cfg_get_strg(label, "root");
- if (p) {
- strcpy (q, "root=");
- strcpy (q + 5, p);
- q = strchr (q, 0);
- *q++ = ' ';
- }
- if (cfg_get_flag(label, "read-only")) {
- strcpy (q, "ro ");
- q += 3;
- }
- if (cfg_get_flag(label, "read-write")) {
- strcpy (q, "rw ");
- q += 3;
- }
- p = cfg_get_strg(label, "ramdisk");
- if (p) {
- strcpy (q, "ramdisk=");
- strcpy (q + 8, p);
- q = strchr (q, 0);
- *q++ = ' ';
- }
- p = cfg_get_strg(label, "initrd-size");
- if (p) {
- strcpy (q, "ramdisk_size=");
- strcpy (q + 13, p);
- q = strchr (q, 0);
- *q++ = ' ';
- }
- if (cfg_get_flag(label, "novideo")) {
- strcpy (q, "video=ofonly");
- q = strchr (q, 0);
- *q++ = ' ';
- }
- p = cfg_get_strg (label, "append");
- if (p) {
- strcpy (q, p);
- q = strchr (q, 0);
- *q++ = ' ';
- }
- *q = 0;
- pause_after = cfg_get_flag (label, "pause-after");
- p = cfg_get_strg(label, "pause-message");
- if (p)
- pause_message = p;
- if (params)
- strcpy(q, params);
-
- return buffer;
+ char *p, *q;
+ static char buffer[2048];
+
+ q = buffer;
+ *q = 0;
+
+ p = cfg_get_strg(label, "literal");
+ if (p) {
+ strcpy(q, p);
+ q = strchr(q, 0);
+ if (params) {
+ if (*p)
+ *q++ = ' ';
+ strcpy(q, params);
+ }
+ return buffer;
+ }
+
+ p = cfg_get_strg(label, "root");
+ if (p) {
+ strcpy (q, "root=");
+ strcpy (q + 5, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ if (cfg_get_flag(label, "read-only")) {
+ strcpy (q, "ro ");
+ q += 3;
+ }
+ if (cfg_get_flag(label, "read-write")) {
+ strcpy (q, "rw ");
+ q += 3;
+ }
+ p = cfg_get_strg(label, "ramdisk");
+ if (p) {
+ strcpy (q, "ramdisk=");
+ strcpy (q + 8, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ p = cfg_get_strg(label, "initrd-size");
+ if (p) {
+ strcpy (q, "ramdisk_size=");
+ strcpy (q + 13, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ if (cfg_get_flag(label, "novideo")) {
+ strcpy (q, "video=ofonly");
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ p = cfg_get_strg (label, "append");
+ if (p) {
+ strcpy (q, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ *q = 0;
+ pause_after = cfg_get_flag (label, "pause-after");
+ p = cfg_get_strg(label, "pause-message");
+ if (p)
+ pause_message = p;
+ if (params)
+ strcpy(q, params);
+
+ return buffer;
}
void check_password(char *str)
{
- int i;
+ int i;
- for (i = 0; i < 3; i++) {
- prom_printf ("\n%sassword: ", str);
- passwdbuff[0] = 0;
- cmdedit ((void (*)(void)) 0, 1);
- prom_printf ("\n");
+ for (i = 0; i < 3; i++) {
+ prom_printf ("\n%sassword: ", str);
+ passwdbuff[0] = 0;
+ cmdedit ((void (*)(void)) 0, 1);
+ prom_printf ("\n");
#ifdef USE_MD5_PASSWORDS
- if (!strncmp (password, "$1$", 3)) {
- if (!check_md5_password(passwdbuff, password))
+ if (!strncmp (password, "$1$", 3)) {
+ if (!check_md5_password(passwdbuff, password))
+ return;
+ }
+ else if (!strcmp (password, passwdbuff))
return;
- }
- else if (!strcmp (password, passwdbuff))
- return;
#else /* !MD5 */
- if (!strcmp (password, passwdbuff))
- return;
+ if (!strcmp (password, passwdbuff))
+ return;
#endif /* USE_MD5_PASSWORDS */
- if (i < 2)
- prom_printf ("Password incorrect. Please try again...");
- }
- prom_printf ("Seems like you don't know the access password. Go away!\n");
- prom_sleep(3);
- prom_interpret("reset-all");
+ if (i < 2)
+ prom_printf ("Password incorrect. Please try again...");
+ }
+ prom_printf ("Seems like you don't know the access password. Go away!\n");
+ prom_sleep(3);
+ prom_interpret("reset-all");
}
int get_params(struct boot_param_t* params)
{
- int defpart;
- char *defdevice = 0;
- char *p, *q, *endp;
- int c, n;
- char *imagename = 0, *label;
- int timeout = -1;
- int beg = 0, end;
- int singlekey = 0;
- int restricted = 0;
- static int first = 1;
- static char bootargs[1024];
- static char imagepath[1024];
- static char initrdpath[1024];
- static char sysmappath[1024];
-
- pause_after = 0;
- memset(params, 0, sizeof(*params));
- params->args = "";
- params->kernel.part = -1;
- params->rd.part = -1;
- params->sysmap.part = -1;
- defpart = boot.part;
+ int defpart;
+ char *defdevice = 0;
+ char *p, *q, *endp;
+ int c, n;
+ char *imagename = 0, *label;
+ int timeout = -1;
+ int beg = 0, end;
+ int singlekey = 0;
+ int restricted = 0;
+ static int first = 1;
+ static char bootargs[1024];
+ static char imagepath[1024];
+ static char initrdpath[1024];
+ static char sysmappath[1024];
+
+ pause_after = 0;
+ memset(params, 0, sizeof(*params));
+ params->args = "";
+ params->kernel.part = -1;
+ params->rd.part = -1;
+ params->sysmap.part = -1;
+ defpart = boot.part;
- cmdinit();
-
- if (first) {
- first = 0;
- prom_get_chosen("bootargs", bootargs, sizeof(bootargs));
- imagename = bootargs;
- word_split(&imagename, ¶ms->args);
- timeout = DEFAULT_TIMEOUT;
- if (imagename) {
- prom_printf("Default supplied on the command line: %s ", imagename);
- if (params->args)
- prom_printf("%s", params->args);
- prom_printf("\n");
- }
- if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
- timeout = simple_strtol(q, NULL, 0);
- }
-
- prom_printf("boot: ");
- c = -1;
- if (timeout != -1) {
- beg = prom_getms();
- if (timeout > 0) {
- end = beg + 100 * timeout;
- do {
- c = prom_nbgetchar();
- } while (c == -1 && prom_getms() <= end);
- }
- if (c == -1)
- c = '\n';
- else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) {
- cbuff[0] = c;
- cbuff[1] = 0;
- }
- }
-
- if (c != -1 && c != '\n' && c != '\r') {
- if (c == '\t') {
- maintabfunc ();
- } else if (c >= ' ') {
- cbuff[0] = c;
- cbuff[1] = 0;
- if ((cfg_get_flag (cbuff, "single-key")) && useconf) {
- imagename = cbuff;
- singlekey = 1;
- prom_printf("%s\n", cbuff);
- }
- }
- }
-
- if (c == '\n' || c == '\r') {
- if (!imagename)
- imagename = cfg_get_default();
- if (imagename)
- prom_printf("%s", imagename);
- if (params->args)
- prom_printf(" %s", params->args);
- prom_printf("\n");
- } else if (!singlekey) {
- cmdedit(maintabfunc, 0);
- prom_printf("\n");
- strcpy(given_bootargs, cbuff);
- given_bootargs_by_user = 1;
- imagename = cbuff;
- word_split(&imagename, ¶ms->args);
- }
-
- /* chrp gets this wrong, force it -- Cort */
- if ( useconf && (!imagename || imagename[0] == 0 ))
- imagename = cfg_get_default();
-
- label = 0;
- defdevice = boot.dev;
-
- if (useconf) {
- defdevice = cfg_get_strg(0, "device");
- p = cfg_get_strg(0, "partition");
- if (p) {
- n = simple_strtol(p, &endp, 10);
- if (endp != p && *endp == 0)
- defpart = n;
- }
- p = cfg_get_strg(0, "pause-message");
- if (p)
- pause_message = p;
- if (cfg_get_flag(0, "restricted"))
- restricted = 1;
- p = cfg_get_strg(imagename, "image");
- if (p && *p) {
- label = imagename;
- imagename = p;
- defdevice = cfg_get_strg(label, "device");
- if(!defdevice) defdevice=boot.dev;
- p = cfg_get_strg(label, "partition");
- if (p) {
- n = simple_strtol(p, &endp, 10);
- if (endp != p && *endp == 0)
+ cmdinit();
+
+ if (first) {
+ first = 0;
+ prom_get_chosen("bootargs", bootargs, sizeof(bootargs));
+ imagename = bootargs;
+ word_split(&imagename, ¶ms->args);
+ timeout = DEFAULT_TIMEOUT;
+ if (imagename) {
+ prom_printf("Default supplied on the command line: %s ", imagename);
+ if (params->args)
+ prom_printf("%s", params->args);
+ prom_printf("\n");
+ }
+ if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
+ timeout = simple_strtol(q, NULL, 0);
+ }
+
+ prom_printf("boot: ");
+ c = -1;
+ if (timeout != -1) {
+ beg = prom_getms();
+ if (timeout > 0) {
+ end = beg + 100 * timeout;
+ do {
+ c = prom_nbgetchar();
+ } while (c == -1 && prom_getms() <= end);
+ }
+ if (c == -1)
+ c = '\n';
+ else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) {
+ cbuff[0] = c;
+ cbuff[1] = 0;
+ }
+ }
+
+ if (c != -1 && c != '\n' && c != '\r') {
+ if (c == '\t') {
+ maintabfunc ();
+ } else if (c >= ' ') {
+ cbuff[0] = c;
+ cbuff[1] = 0;
+ if ((cfg_get_flag (cbuff, "single-key")) && useconf) {
+ imagename = cbuff;
+ singlekey = 1;
+ prom_printf("%s\n", cbuff);
+ }
+ }
+ }
+
+ if (c == '\n' || c == '\r') {
+ if (!imagename)
+ imagename = cfg_get_default();
+ if (imagename)
+ prom_printf("%s", imagename);
+ if (params->args)
+ prom_printf(" %s", params->args);
+ prom_printf("\n");
+ } else if (!singlekey) {
+ cmdedit(maintabfunc, 0);
+ prom_printf("\n");
+ strcpy(given_bootargs, cbuff);
+ given_bootargs_by_user = 1;
+ imagename = cbuff;
+ word_split(&imagename, ¶ms->args);
+ }
+
+ /* chrp gets this wrong, force it -- Cort */
+ if ( useconf && (!imagename || imagename[0] == 0 ))
+ imagename = cfg_get_default();
+
+ label = 0;
+ defdevice = boot.dev;
+
+ if (useconf) {
+ defdevice = cfg_get_strg(0, "device");
+ p = cfg_get_strg(0, "partition");
+ if (p) {
+ n = simple_strtol(p, &endp, 10);
+ if (endp != p && *endp == 0)
defpart = n;
- }
- if (cfg_get_flag(label, "restricted"))
- restricted = 1;
- if (label) {
- if (params->args && password && restricted)
- check_password ("To specify image arguments you must enter the p");
- else if (password && !restricted)
- check_password ("P");
- }
- params->args = make_params(label, params->args);
- }
- }
-
- if (!strcmp (imagename, "help")) {
- prom_printf(
- "\nPress the tab key for a list of defined images.\n"
- "The label marked with a \"*\" is is the default image, "
- "press <return> to boot it.\n\n"
- "To boot any other label simply type its name and press <return>.\n\n"
- "To boot a kernel image which is not defined in the yaboot configuration \n"
- "file, enter the kernel image name as [device:][partno],/path, where \n"
- "\"device:\" is the OpenFirmware device path to the disk the image \n"
- "resides on, and \"partno\" is the partition number the image resides on.\n\n"
- "If you omit \"device:\" and \"partno\" yaboot will use the values of \n"
- "\"device=\" and \"partition=\" in yaboot.conf, right now those are set to: \n"
- "device=%s\n"
- "partition=%d\n\n", defdevice, defpart);
- return 0;
- }
-
- if (!strcmp (imagename, "halt")) {
- if (password)
- check_password ("P");
- prom_pause();
- return 0;
- }
- if (!strcmp (imagename, "bye")) {
- if (password) {
- check_password ("P");
- return 1;
- }
- return 1;
- }
-
- if (imagename[0] == '$') {
- /* forth command string */
- if (password)
- check_password ("P");
- prom_interpret(imagename+1);
- return 0;
- }
-
- strncpy(imagepath, imagename, 1024);
-
- if (!label && password)
- check_password ("To boot a custom image you must enter the p");
-
- if (!parse_device_path(imagepath, defdevice, defpart,
- "/vmlinux", ¶ms->kernel)) {
- prom_printf("%s: Unable to parse\n", imagepath);
- return 0;
- }
- DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev,
- params->kernel.part, params->kernel.file);
-
- if (useconf) {
- p = cfg_get_strg(label, "initrd");
- if (p && *p) {
- DEBUG_F("Parsing initrd path <%s>\n", p);
- strncpy(initrdpath, p, 1024);
- if (!parse_device_path(initrdpath, defdevice, defpart,
- "/root.bin", ¶ms->rd)) {
- prom_printf("%s: Unable to parse\n", imagepath);
- return 0;
- }
- }
- p = cfg_get_strg(label, "sysmap");
- if (p && *p) {
- DEBUG_F("Parsing sysmap path <%s>\n", p);
- strncpy(sysmappath, p, 1024);
- if (!parse_device_path(sysmappath, defdevice, defpart,
- "/boot/System.map", ¶ms->sysmap)) {
- prom_printf("%s: Unable to parse\n", imagepath);
- return 0;
- }
- }
- }
- return 0;
+ }
+ p = cfg_get_strg(0, "pause-message");
+ if (p)
+ pause_message = p;
+ if (cfg_get_flag(0, "restricted"))
+ restricted = 1;
+ p = cfg_get_strg(imagename, "image");
+ if (p && *p) {
+ label = imagename;
+ imagename = p;
+ defdevice = cfg_get_strg(label, "device");
+ if(!defdevice) defdevice=boot.dev;
+ p = cfg_get_strg(label, "partition");
+ if (p) {
+ n = simple_strtol(p, &endp, 10);
+ if (endp != p && *endp == 0)
+ defpart = n;
+ }
+ if (cfg_get_flag(label, "restricted"))
+ restricted = 1;
+ if (label) {
+ if (params->args && password && restricted)
+ check_password ("To specify image arguments you must enter the p");
+ else if (password && !restricted)
+ check_password ("P");
+ }
+ params->args = make_params(label, params->args);
+ }
+ }
+
+ if (!strcmp (imagename, "help")) {
+ prom_printf(
+ "\nPress the tab key for a list of defined images.\n"
+ "The label marked with a \"*\" is is the default image, "
+ "press <return> to boot it.\n\n"
+ "To boot any other label simply type its name and press <return>.\n\n"
+ "To boot a kernel image which is not defined in the yaboot configuration \n"
+ "file, enter the kernel image name as [device:][partno],/path, where \n"
+ "\"device:\" is the OpenFirmware device path to the disk the image \n"
+ "resides on, and \"partno\" is the partition number the image resides on.\n"
+ "Note that the comma (,) is only required if you specify an OpenFirmware\n"
+ "device, if you only specify a filename you should not start it with a \",\"\n\n"
+ "If you omit \"device:\" and \"partno\" yaboot will use the values of \n"
+ "\"device=\" and \"partition=\" in yaboot.conf, right now those are set to: \n"
+ "device=%s\n"
+ "partition=%d\n\n", defdevice, defpart);
+ return 0;
+ }
+
+ if (!strcmp (imagename, "halt")) {
+ if (password)
+ check_password ("P");
+ prom_pause();
+ return 0;
+ }
+ if (!strcmp (imagename, "bye")) {
+ if (password) {
+ check_password ("P");
+ return 1;
+ }
+ return 1;
+ }
+
+ if (imagename[0] == '$') {
+ /* forth command string */
+ if (password)
+ check_password ("P");
+ prom_interpret(imagename+1);
+ return 0;
+ }
+
+ strncpy(imagepath, imagename, 1024);
+
+ if (!label && password)
+ check_password ("To boot a custom image you must enter the p");
+
+ if (!parse_device_path(imagepath, defdevice, defpart,
+ "/vmlinux", ¶ms->kernel)) {
+ prom_printf("%s: Unable to parse\n", imagepath);
+ return 0;
+ }
+ DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev,
+ params->kernel.part, params->kernel.file);
+
+ if (useconf) {
+ p = cfg_get_strg(label, "initrd");
+ if (p && *p) {
+ DEBUG_F("Parsing initrd path <%s>\n", p);
+ strncpy(initrdpath, p, 1024);
+ if (!parse_device_path(initrdpath, defdevice, defpart,
+ "/root.bin", ¶ms->rd)) {
+ prom_printf("%s: Unable to parse\n", imagepath);
+ return 0;
+ }
+ }
+ p = cfg_get_strg(label, "sysmap");
+ if (p && *p) {
+ DEBUG_F("Parsing sysmap path <%s>\n", p);
+ strncpy(sysmappath, p, 1024);
+ if (!parse_device_path(sysmappath, defdevice, defpart,
+ "/boot/System.map", ¶ms->sysmap)) {
+ prom_printf("%s: Unable to parse\n", imagepath);
+ return 0;
+ }
+ }
+ }
+ return 0;
}
/* This is derived from quik core. To be changed to first parse the headers
{
#define MAX_HEADERS 32
- struct boot_file_t file;
- int result;
- static struct boot_param_t params;
- void *initrd_base;
- unsigned long initrd_size;
- void *sysmap_base;
- unsigned long sysmap_size;
- kernel_entry_t kernel_entry;
- struct bi_record* birec;
- char* loc=NULL;
- loadinfo_t loadinfo;
- void *initrd_more,*initrd_want;
- unsigned long initrd_read;
+ struct boot_file_t file;
+ int result;
+ static struct boot_param_t params;
+ void *initrd_base;
+ unsigned long initrd_size;
+ void *sysmap_base;
+ unsigned long sysmap_size;
+ kernel_entry_t kernel_entry;
+ struct bi_record* birec;
+ char* loc=NULL;
+ loadinfo_t loadinfo;
+ void *initrd_more,*initrd_want;
+ unsigned long initrd_read;
- loadinfo.load_loc = 0;
+ loadinfo.load_loc = 0;
- for (;;) {
- initrd_size = 0;
- initrd_base = 0;
- sysmap_base = 0;
- sysmap_size = 0;
+ for (;;) {
+ initrd_size = 0;
+ initrd_base = 0;
+ sysmap_base = 0;
+ sysmap_size = 0;
- if (get_params(¶ms))
- return;
- if (!params.kernel.file)
- continue;
+ if (get_params(¶ms))
+ return;
+ if (!params.kernel.file)
+ continue;
- prom_printf("Please wait, loading kernel...\n");
-
- memset(&file, 0, sizeof(file));
-
- if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.kernel.file[0] != '/'
- && params.kernel.file[0] != '\\') {
- loc=(char*)malloc(strlen(params.kernel.file)+3);
- if (!loc) {
- prom_printf ("malloc error\n");
- goto next;
- }
- strcpy(loc,boot.file);
- strcat(loc,params.kernel.file);
- free(params.kernel.file);
- params.kernel.file=loc;
- }
- result = open_file(¶ms.kernel, &file);
- if (result != FILE_ERR_OK) {
- prom_printf("%s:%d,", params.kernel.dev, params.kernel.part);
- prom_perror(result, params.kernel.file);
- goto next;
- }
-
- /* Read the Elf e_ident, e_type and e_machine fields to
- * determine Elf file type
- */
- if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) {
- prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n");
- file.fs->close(&file);
- memset(&file, 0, sizeof(file));
- goto next;
- }
-
- if (is_elf32(&loadinfo)) {
- if (!load_elf32(&file, &loadinfo)) {
- file.fs->close(&file);
- memset(&file, 0, sizeof(file));
- goto next;
- }
- prom_printf(" Elf32 kernel loaded...\n");
- } else if (is_elf64(&loadinfo)) {
- if (!load_elf64(&file, &loadinfo)) {
- file.fs->close(&file);
- memset(&file, 0, sizeof(file));
- goto next;
- }
- prom_printf(" Elf64 kernel loaded...\n");
- } else {
- prom_printf ("%s: Not a valid ELF image\n", params.kernel.file);
- file.fs->close(&file);
- memset(&file, 0, sizeof(file));
- goto next;
- }
- file.fs->close(&file);
- memset(&file, 0, sizeof(file));
-
- /* If sysmap, load it.
- */
- if (params.sysmap.file) {
- prom_printf("Loading System.map ...\n");
- if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.sysmap.file[0] != '/'
- && params.sysmap.file[0] != '\\') {
- if (loc) free(loc);
- loc=(char*)malloc(strlen(params.sysmap.file)+3);
- if (!loc) {
- prom_printf ("malloc error\n");
- goto next;
- }
- strcpy(loc,boot.file);
- strcat(loc,params.sysmap.file);
- free(params.sysmap.file);
- params.sysmap.file=loc;
- }
-
- result = open_file(¶ms.sysmap, &file);
- if (result != FILE_ERR_OK) {
- prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part);
- prom_perror(result, params.sysmap.file);
- }
- else {
- sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
- if (sysmap_base == (void *)-1) {
- prom_printf("Claim failed for sysmap memory\n");
- sysmap_base = 0;
- } else {
- sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
- if (sysmap_size == 0)
- sysmap_base = 0;
- else
- ((char *)sysmap_base)[sysmap_size++] = 0;
- }
- file.fs->close(&file);
- memset(&file, 0, sizeof(file));
- }
- if (sysmap_base) {
- prom_printf("System.map loaded at %p, size: %lu Kbytes\n",
- sysmap_base, sysmap_size >> 10);
- loadinfo.memsize += _ALIGN(0x100000, 0x1000);
- } else {
- prom_printf("System.map load failed !\n");
- prom_pause();
- }
- }
-
- /* If ramdisk, load it. For now, we can't tell the size it will be
- * so we claim an arbitrary amount of 4Mb
- */
- if (params.rd.file) {
- if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.rd.file[0] != '/'
- && params.kernel.file[0] != '\\')
- {
- if (loc) free(loc);
- loc=(char*)malloc(strlen(params.rd.file)+3);
- if (!loc) {
- prom_printf ("Malloc error\n");
+ prom_printf("Please wait, loading kernel...\n");
+
+ memset(&file, 0, sizeof(file));
+
+ if (strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.kernel.file[0] != '/'
+ && params.kernel.file[0] != '\\') {
+ loc=(char*)malloc(strlen(params.kernel.file)+3);
+ if (!loc) {
+ prom_printf ("malloc error\n");
goto next;
- }
- strcpy(loc,boot.file);
- strcat(loc,params.rd.file);
- free(params.rd.file);
- params.rd.file=loc;
- }
- prom_printf("Loading ramdisk...\n");
- result = open_file(¶ms.rd, &file);
- if (result != FILE_ERR_OK) {
- prom_printf("%s:%d,", params.rd.dev, params.rd.part);
- prom_perror(result, params.rd.file);
- }
- else {
+ }
+ strcpy(loc,boot.file);
+ strcat(loc,params.kernel.file);
+ free(params.kernel.file);
+ params.kernel.file=loc;
+ }
+ result = open_file(¶ms.kernel, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("%s:%d,", params.kernel.dev, params.kernel.part);
+ prom_perror(result, params.kernel.file);
+ goto next;
+ }
+
+ /* Read the Elf e_ident, e_type and e_machine fields to
+ * determine Elf file type
+ */
+ if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) {
+ prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n");
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+
+ if (is_elf32(&loadinfo)) {
+ if (!load_elf32(&file, &loadinfo)) {
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+ prom_printf(" Elf32 kernel loaded...\n");
+ } else if (is_elf64(&loadinfo)) {
+ if (!load_elf64(&file, &loadinfo)) {
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+ prom_printf(" Elf64 kernel loaded...\n");
+ } else {
+ prom_printf ("%s: Not a valid ELF image\n", params.kernel.file);
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ goto next;
+ }
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+
+ /* If sysmap, load it.
+ */
+ if (params.sysmap.file) {
+ prom_printf("Loading System.map ...\n");
+ if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.sysmap.file[0] != '/'
+ && params.sysmap.file[0] != '\\') {
+ if (loc) free(loc);
+ loc=(char*)malloc(strlen(params.sysmap.file)+3);
+ if (!loc) {
+ prom_printf ("malloc error\n");
+ goto next;
+ }
+ strcpy(loc,boot.file);
+ strcat(loc,params.sysmap.file);
+ free(params.sysmap.file);
+ params.sysmap.file=loc;
+ }
+
+ result = open_file(¶ms.sysmap, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("%s:%d,", params.sysmap.dev, params.sysmap.part);
+ prom_perror(result, params.sysmap.file);
+ }
+ else {
+ sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
+ if (sysmap_base == (void *)-1) {
+ prom_printf("Claim failed for sysmap memory\n");
+ sysmap_base = 0;
+ } else {
+ sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
+ if (sysmap_size == 0)
+ sysmap_base = 0;
+ else
+ ((char *)sysmap_base)[sysmap_size++] = 0;
+ }
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ }
+ if (sysmap_base) {
+ prom_printf("System.map loaded at %p, size: %lu Kbytes\n",
+ sysmap_base, sysmap_size >> 10);
+ loadinfo.memsize += _ALIGN(0x100000, 0x1000);
+ } else {
+ prom_printf("System.map load failed !\n");
+ prom_pause();
+ }
+ }
+
+ /* If ramdisk, load it. For now, we can't tell the size it will be
+ * so we claim an arbitrary amount of 4Mb
+ */
+ if (params.rd.file) {
+ if(strlen(boot.file) && !strcmp(boot.file,"\\\\") && params.rd.file[0] != '/'
+ && params.kernel.file[0] != '\\')
+ {
+ if (loc) free(loc);
+ loc=(char*)malloc(strlen(params.rd.file)+3);
+ if (!loc) {
+ prom_printf ("Malloc error\n");
+ goto next;
+ }
+ strcpy(loc,boot.file);
+ strcat(loc,params.rd.file);
+ free(params.rd.file);
+ params.rd.file=loc;
+ }
+ prom_printf("Loading ramdisk...\n");
+ result = open_file(¶ms.rd, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("%s:%d,", params.rd.dev, params.rd.part);
+ prom_perror(result, params.rd.file);
+ }
+ else {
#define INITRD_CHUNKSIZE 0x400000
- initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
- if (initrd_base == (void *)-1) {
- prom_printf("Claim failed for initrd memory\n");
- initrd_base = 0;
- } else {
- initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base);
- if (initrd_size == 0)
- initrd_base = 0;
- initrd_read = initrd_size;
- initrd_more = initrd_base;
- while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */
- initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE);
- initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
- if (initrd_more != initrd_want) {
- prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
- break;
- }
- initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
- DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read);
- initrd_size += initrd_read;
+ initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0);
+ if (initrd_base == (void *)-1) {
+ prom_printf("Claim failed for initrd memory\n");
+ initrd_base = 0;
+ } else {
+ initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base);
+ if (initrd_size == 0)
+ initrd_base = 0;
+ initrd_read = initrd_size;
+ initrd_more = initrd_base;
+ while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */
+ initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE);
+ initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0);
+ if (initrd_more != initrd_want) {
+ prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more);
+ break;
+ }
+ initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
+ DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read);
+ initrd_size += initrd_read;
+ }
}
- }
- file.fs->close(&file);
- memset(&file, 0, sizeof(file));
- }
- if (initrd_base)
- prom_printf("ramdisk loaded at %p, size: %lu Kbytes\n",
- initrd_base, initrd_size >> 10);
- else {
- prom_printf("ramdisk load failed !\n");
- prom_pause();
- }
- }
-
- DEBUG_F("setting kernel args to: %s\n", params.args);
- prom_setargs(params.args);
- DEBUG_F("flushing icache...");
- flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize);
- DEBUG_F(" done\n");
-
- /*
- * Fill mew boot infos
- *
- * The birec is low on memory, probably inside the malloc pool, so
- * we don't write it earlier. At this point, we should not use anything
- * coming from the malloc pool
- */
- birec = (struct bi_record *)_ALIGN(loadinfo.filesize+(1<<20)-1,(1<<20));
-
- /* We make sure it's mapped. We map only 64k for now, it's plenty enough
- * we don't claim since this precise memory range may already be claimed
- * by the malloc pool
- */
- prom_map (birec, birec, 0x10000);
- DEBUG_F("birec at %p\n", birec);
- DEBUG_SLEEP;
-
- birec->tag = BI_FIRST;
- birec->size = sizeof(struct bi_record);
- birec = (struct bi_record *)((unsigned long)birec + birec->size);
+ file.fs->close(&file);
+ memset(&file, 0, sizeof(file));
+ }
+ if (initrd_base)
+ prom_printf("ramdisk loaded at %p, size: %lu Kbytes\n",
+ initrd_base, initrd_size >> 10);
+ else {
+ prom_printf("ramdisk load failed !\n");
+ prom_pause();
+ }
+ }
+
+ DEBUG_F("setting kernel args to: %s\n", params.args);
+ prom_setargs(params.args);
+ DEBUG_F("flushing icache...");
+ flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize);
+ DEBUG_F(" done\n");
+
+/*
+ * Fill mew boot infos
+ *
+ * The birec is low on memory, probably inside the malloc pool, so
+ * we don't write it earlier. At this point, we should not use anything
+ * coming from the malloc pool
+ */
+ birec = (struct bi_record *)_ALIGN(loadinfo.filesize+(1<<20)-1,(1<<20));
+
+/* We make sure it's mapped. We map only 64k for now, it's plenty enough
+ * we don't claim since this precise memory range may already be claimed
+ * by the malloc pool
+ */
+ prom_map (birec, birec, 0x10000);
+ DEBUG_F("birec at %p\n", birec);
+ DEBUG_SLEEP;
+
+ birec->tag = BI_FIRST;
+ birec->size = sizeof(struct bi_record);
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
- birec->tag = BI_BOOTLOADER_ID;
- sprintf( (char *)birec->data, "yaboot");
- birec->size = sizeof(struct bi_record) + strlen("yaboot") + 1;
- birec = (struct bi_record *)((unsigned long)birec + birec->size);
+ birec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)birec->data, "yaboot");
+ birec->size = sizeof(struct bi_record) + strlen("yaboot") + 1;
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
- birec->tag = BI_MACHTYPE;
- birec->data[0] = _machine;
- birec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- birec = (struct bi_record *)((unsigned long)birec + birec->size);
-
- if (sysmap_base) {
- birec->tag = BI_SYSMAP;
- birec->data[0] = (unsigned long)sysmap_base;
- birec->data[1] = sysmap_size;
- birec->size = sizeof(struct bi_record) + sizeof(unsigned long)*2;
- birec = (struct bi_record *)((unsigned long)birec + birec->size);
- }
- birec->tag = BI_LAST;
- birec->size = sizeof(struct bi_record);
- birec = (struct bi_record *)((unsigned long)birec + birec->size);
-
- /* compute the kernel's entry point. */
- kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc;
-
- DEBUG_F("Kernel entry point = %p\n", kernel_entry);
- DEBUG_F("kernel: arg1 = %p,\n"
- " arg2 = 0x%08lx,\n"
- " prom = %p,\n"
- " arg4 = %d,\n"
- " arg5 = %d\n\n",
- initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
-
- DEBUG_F("Entering kernel...\n");
-
- /* call the kernel with our stack. */
- kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
- continue;
-next:
- ; /* do nothing */
- }
+ birec->tag = BI_MACHTYPE;
+ birec->data[0] = _machine;
+ birec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+
+ if (sysmap_base) {
+ birec->tag = BI_SYSMAP;
+ birec->data[0] = (unsigned long)sysmap_base;
+ birec->data[1] = sysmap_size;
+ birec->size = sizeof(struct bi_record) + sizeof(unsigned long)*2;
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+ }
+ birec->tag = BI_LAST;
+ birec->size = sizeof(struct bi_record);
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+
+ /* compute the kernel's entry point. */
+ kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc;
+
+ DEBUG_F("Kernel entry point = %p\n", kernel_entry);
+ DEBUG_F("kernel: arg1 = %p,\n"
+ " arg2 = 0x%08lx,\n"
+ " prom = %p,\n"
+ " arg4 = %d,\n"
+ " arg5 = %d\n\n",
+ initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
+
+ DEBUG_F("Entering kernel...\n");
+
+ /* call the kernel with our stack. */
+ kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
+ continue;
+ next:
+ ; /* do nothing */
+ }
}
static int
load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
{
- int i;
- Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
- Elf32_Phdr *p, *ph;
- int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident);
- unsigned long addr, loadaddr;
-
- /* Read the rest of the Elf header... */
- if ((*(file->fs->read))(file, size, &e->e_version) < size) {
- prom_printf("\nCan't read Elf32 image header\n");
- return 0;
- }
-
- DEBUG_F("Elf32 header:\n");
- DEBUG_F(" e.e_type = %d\n", (int)e->e_type);
- DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine);
- DEBUG_F(" e.e_version = %d\n", (int)e->e_version);
- DEBUG_F(" e.e_entry = 0x%08x\n", (int)e->e_entry);
- DEBUG_F(" e.e_phoff = 0x%08x\n", (int)e->e_phoff);
- DEBUG_F(" e.e_shoff = 0x%08x\n", (int)e->e_shoff);
- DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags);
- DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
- DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
- DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum);
-
- loadinfo->entry = e->e_entry;
-
- if (e->e_phnum > MAX_HEADERS) {
- prom_printf ("Can only load kernels with one program header\n");
- return 0;
- }
-
- ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum);
- if (!ph) {
- prom_printf ("Malloc error\n");
- return 0;
- }
-
- /* Now, we read the section header */
- if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
- prom_printf ("seek error\n");
- return 0;
- }
- if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) !=
- sizeof(Elf32_Phdr) * e->e_phnum) {
- prom_printf ("read error\n");
- return 0;
- }
-
- /* Scan through the program header
- * HACK: We must return the _memory size of the kernel image, not the
- * file size (because we have to leave room before other boot
- * infos. This code works as a side effect of the fact that
- * we have one section and vaddr == p_paddr
- */
- loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
- p = ph;
- for (i = 0; i < e->e_phnum; ++i, ++p) {
- if (p->p_type != PT_LOAD || p->p_offset == 0)
- continue;
- if (loadinfo->memsize == 0) {
- loadinfo->offset = p->p_offset;
- loadinfo->memsize = p->p_memsz;
- loadinfo->filesize = p->p_filesz;
- loadinfo->load_loc = p->p_vaddr;
- } else {
- loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
- loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
- }
- }
-
- if (loadinfo->memsize == 0) {
- prom_printf("Can't find a loadable segment !\n");
- return 0;
- }
-
- /* leave some room (1Mb) for boot infos */
- loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
- /* Claim OF memory */
- DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
-
- /* On some systems, loadaddr may already be claimed, so try some
- * other nearby addresses before giving up.
- */
- loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC32 ||
- e->e_entry == 0) ? KERNELADDR : e->e_entry;
- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
- if (loadinfo->base != (void *)-1) break;
- }
- if (loadinfo->base == (void *)-1) {
- prom_printf("Claim error, can't allocate kernel memory\n");
- return 0;
- }
-
- DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
- loadinfo->base, loadinfo->memsize);
- DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
- loadaddr, loadinfo->memsize);
-
- /* Load the program segments... */
- p = ph;
- for (i = 0; i < e->e_phnum; ++i, ++p) {
- unsigned long offset;
- if (p->p_type != PT_LOAD || p->p_offset == 0)
- continue;
-
- /* Now, we skip to the image itself */
- if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
- prom_printf ("Seek error\n");
- prom_release(loadinfo->base, loadinfo->memsize);
- return 0;
- }
- offset = p->p_vaddr - loadinfo->load_loc;
- if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
- prom_printf ("Read failed\n");
- prom_release(loadinfo->base, loadinfo->memsize);
- return 0;
- }
- }
-
- free(ph);
+ int i;
+ Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
+ Elf32_Phdr *p, *ph;
+ int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident);
+ unsigned long addr, loadaddr;
+
+ /* Read the rest of the Elf header... */
+ if ((*(file->fs->read))(file, size, &e->e_version) < size) {
+ prom_printf("\nCan't read Elf32 image header\n");
+ return 0;
+ }
+
+ DEBUG_F("Elf32 header:\n");
+ DEBUG_F(" e.e_type = %d\n", (int)e->e_type);
+ DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine);
+ DEBUG_F(" e.e_version = %d\n", (int)e->e_version);
+ DEBUG_F(" e.e_entry = 0x%08x\n", (int)e->e_entry);
+ DEBUG_F(" e.e_phoff = 0x%08x\n", (int)e->e_phoff);
+ DEBUG_F(" e.e_shoff = 0x%08x\n", (int)e->e_shoff);
+ DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags);
+ DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
+ DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+ DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum);
+
+ loadinfo->entry = e->e_entry;
+
+ if (e->e_phnum > MAX_HEADERS) {
+ prom_printf ("Can only load kernels with one program header\n");
+ return 0;
+ }
+
+ ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum);
+ if (!ph) {
+ prom_printf ("Malloc error\n");
+ return 0;
+ }
+
+ /* Now, we read the section header */
+ if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
+ prom_printf ("seek error\n");
+ return 0;
+ }
+ if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) !=
+ sizeof(Elf32_Phdr) * e->e_phnum) {
+ prom_printf ("read error\n");
+ return 0;
+ }
+
+ /* Scan through the program header
+ * HACK: We must return the _memory size of the kernel image, not the
+ * file size (because we have to leave room before other boot
+ * infos. This code works as a side effect of the fact that
+ * we have one section and vaddr == p_paddr
+ */
+ loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+ if (loadinfo->memsize == 0) {
+ loadinfo->offset = p->p_offset;
+ loadinfo->memsize = p->p_memsz;
+ loadinfo->filesize = p->p_filesz;
+ loadinfo->load_loc = p->p_vaddr;
+ } else {
+ loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
+ loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
+ }
+ }
+
+ if (loadinfo->memsize == 0) {
+ prom_printf("Can't find a loadable segment !\n");
+ return 0;
+ }
+
+ /* leave some room (1Mb) for boot infos */
+ loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
+ /* Claim OF memory */
+ DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
+
+ /* On some systems, loadaddr may already be claimed, so try some
+ * other nearby addresses before giving up.
+ */
+ loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC32 ||
+ e->e_entry == 0) ? KERNELADDR : e->e_entry;
+ for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
+ loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
+ if (loadinfo->base != (void *)-1) break;
+ }
+ if (loadinfo->base == (void *)-1) {
+ prom_printf("Claim error, can't allocate kernel memory\n");
+ return 0;
+ }
+
+ DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
+ loadinfo->base, loadinfo->memsize);
+ DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+ loadaddr, loadinfo->memsize);
+
+ /* Load the program segments... */
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ unsigned long offset;
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+
+ /* Now, we skip to the image itself */
+ if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
+ prom_printf ("Seek error\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ offset = p->p_vaddr - loadinfo->load_loc;
+ if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+ prom_printf ("Read failed\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ }
+
+ free(ph);
- /* Return success at loading the Elf32 kernel */
- return 1;
+ /* Return success at loading the Elf32 kernel */
+ return 1;
}
static int
load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
{
- int i;
- Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
- Elf64_Phdr *p, *ph;
- int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident);
- unsigned long addr, loadaddr;
-
- /* Read the rest of the Elf header... */
- if ((*(file->fs->read))(file, size, &e->e_version) < size) {
- prom_printf("\nCan't read Elf64 image header\n");
- return 0;
- }
-
- DEBUG_F("Elf64 header:\n");
- DEBUG_F(" e.e_type = %d\n", (int)e->e_type);
- DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine);
- DEBUG_F(" e.e_version = %d\n", (int)e->e_version);
- DEBUG_F(" e.e_entry = 0x%016lx\n", (long)e->e_entry);
- DEBUG_F(" e.e_phoff = 0x%016lx\n", (long)e->e_phoff);
- DEBUG_F(" e.e_shoff = 0x%016lx\n", (long)e->e_shoff);
- DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags);
- DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
- DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
- DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum);
-
- loadinfo->entry = e->e_entry;
-
- if (e->e_phnum > MAX_HEADERS) {
- prom_printf ("Can only load kernels with one program header\n");
- return 0;
- }
-
- ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum);
- if (!ph) {
- prom_printf ("Malloc error\n");
- return 0;
- }
-
- /* Now, we read the section header */
- if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
- prom_printf ("Seek error\n");
- return 0;
- }
- if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) !=
- sizeof(Elf64_Phdr) * e->e_phnum) {
- prom_printf ("Read error\n");
- return 0;
- }
-
- /* Scan through the program header
- * HACK: We must return the _memory size of the kernel image, not the
- * file size (because we have to leave room before other boot
- * infos. This code works as a side effect of the fact that
- * we have one section and vaddr == p_paddr
- */
- loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
- p = ph;
- for (i = 0; i < e->e_phnum; ++i, ++p) {
- if (p->p_type != PT_LOAD || p->p_offset == 0)
- continue;
- if (loadinfo->memsize == 0) {
- loadinfo->offset = p->p_offset;
- loadinfo->memsize = p->p_memsz;
- loadinfo->filesize = p->p_filesz;
- loadinfo->load_loc = p->p_vaddr;
- } else {
- loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
- loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
- }
- }
-
- if (loadinfo->memsize == 0) {
- prom_printf("Can't find a loadable segment !\n");
- return 0;
- }
-
- /* leave some room (1Mb) for boot infos */
- loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
- /* Claim OF memory */
- DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
-
- /* On some systems, loadaddr may already be claimed, so try some
- * other nearby addresses before giving up.
- */
- loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC64) ? KERNELADDR : e->e_entry;
- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
- if (loadinfo->base != (void *)-1) break;
- }
- if (loadinfo->base == (void *)-1) {
- prom_printf("Claim error, can't allocate kernel memory\n");
- return 0;
- }
-
- DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
- loadinfo->base, loadinfo->memsize);
- DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
- loadaddr, loadinfo->memsize);
-
- /* Load the program segments... */
- p = ph;
- for (i = 0; i < e->e_phnum; ++i, ++p) {
- unsigned long offset;
- if (p->p_type != PT_LOAD || p->p_offset == 0)
- continue;
-
- /* Now, we skip to the image itself */
- if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
- prom_printf ("Seek error\n");
- prom_release(loadinfo->base, loadinfo->memsize);
- return 0;
- }
- offset = p->p_vaddr - loadinfo->load_loc;
- if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
- prom_printf ("Read failed\n");
- prom_release(loadinfo->base, loadinfo->memsize);
- return 0;
- }
- }
+ int i;
+ Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
+ Elf64_Phdr *p, *ph;
+ int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident);
+ unsigned long addr, loadaddr;
+
+ /* Read the rest of the Elf header... */
+ if ((*(file->fs->read))(file, size, &e->e_version) < size) {
+ prom_printf("\nCan't read Elf64 image header\n");
+ return 0;
+ }
+
+ DEBUG_F("Elf64 header:\n");
+ DEBUG_F(" e.e_type = %d\n", (int)e->e_type);
+ DEBUG_F(" e.e_machine = %d\n", (int)e->e_machine);
+ DEBUG_F(" e.e_version = %d\n", (int)e->e_version);
+ DEBUG_F(" e.e_entry = 0x%016lx\n", (long)e->e_entry);
+ DEBUG_F(" e.e_phoff = 0x%016lx\n", (long)e->e_phoff);
+ DEBUG_F(" e.e_shoff = 0x%016lx\n", (long)e->e_shoff);
+ DEBUG_F(" e.e_flags = %d\n", (int)e->e_flags);
+ DEBUG_F(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
+ DEBUG_F(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+ DEBUG_F(" e.e_phnum = %d\n", (int)e->e_phnum);
+
+ loadinfo->entry = e->e_entry;
+
+ if (e->e_phnum > MAX_HEADERS) {
+ prom_printf ("Can only load kernels with one program header\n");
+ return 0;
+ }
- free(ph);
+ ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum);
+ if (!ph) {
+ prom_printf ("Malloc error\n");
+ return 0;
+ }
+
+ /* Now, we read the section header */
+ if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
+ prom_printf ("Seek error\n");
+ return 0;
+ }
+ if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) !=
+ sizeof(Elf64_Phdr) * e->e_phnum) {
+ prom_printf ("Read error\n");
+ return 0;
+ }
+
+ /* Scan through the program header
+ * HACK: We must return the _memory size of the kernel image, not the
+ * file size (because we have to leave room before other boot
+ * infos. This code works as a side effect of the fact that
+ * we have one section and vaddr == p_paddr
+ */
+ loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+ if (loadinfo->memsize == 0) {
+ loadinfo->offset = p->p_offset;
+ loadinfo->memsize = p->p_memsz;
+ loadinfo->filesize = p->p_filesz;
+ loadinfo->load_loc = p->p_vaddr;
+ } else {
+ loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
+ loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
+ }
+ }
+
+ if (loadinfo->memsize == 0) {
+ prom_printf("Can't find a loadable segment !\n");
+ return 0;
+ }
+
+ /* leave some room (1Mb) for boot infos */
+ loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
+ /* Claim OF memory */
+ DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
+
+ /* On some systems, loadaddr may already be claimed, so try some
+ * other nearby addresses before giving up.
+ */
+ loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC64) ? KERNELADDR : e->e_entry;
+ for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
+ loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
+ if (loadinfo->base != (void *)-1) break;
+ }
+ if (loadinfo->base == (void *)-1) {
+ prom_printf("Claim error, can't allocate kernel memory\n");
+ return 0;
+ }
+
+ DEBUG_F("After ELF parsing, load base: %p, mem_sz: 0x%08lx\n",
+ loadinfo->base, loadinfo->memsize);
+ DEBUG_F(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+ loadaddr, loadinfo->memsize);
+
+ /* Load the program segments... */
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ unsigned long offset;
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+
+ /* Now, we skip to the image itself */
+ if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
+ prom_printf ("Seek error\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ offset = p->p_vaddr - loadinfo->load_loc;
+ if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+ prom_printf ("Read failed\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ }
+
+ free(ph);
- /* Return success at loading the Elf64 kernel */
- return 1;
+ /* Return success at loading the Elf64 kernel */
+ return 1;
}
static int
is_elf32(loadinfo_t *loadinfo)
{
- Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
-
- return (e->e_ident[EI_MAG0] == ELFMAG0 &&
- e->e_ident[EI_MAG1] == ELFMAG1 &&
- e->e_ident[EI_MAG2] == ELFMAG2 &&
- e->e_ident[EI_MAG3] == ELFMAG3 &&
- e->e_ident[EI_CLASS] == ELFCLASS32 &&
- e->e_ident[EI_DATA] == ELFDATA2MSB &&
- e->e_type == ET_EXEC &&
- e->e_machine == EM_PPC);
+ Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
+
+ return (e->e_ident[EI_MAG0] == ELFMAG0 &&
+ e->e_ident[EI_MAG1] == ELFMAG1 &&
+ e->e_ident[EI_MAG2] == ELFMAG2 &&
+ e->e_ident[EI_MAG3] == ELFMAG3 &&
+ e->e_ident[EI_CLASS] == ELFCLASS32 &&
+ e->e_ident[EI_DATA] == ELFDATA2MSB &&
+ e->e_type == ET_EXEC &&
+ e->e_machine == EM_PPC);
}
static int
is_elf64(loadinfo_t *loadinfo)
{
- Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
-
- return (e->e_ident[EI_MAG0] == ELFMAG0 &&
- e->e_ident[EI_MAG1] == ELFMAG1 &&
- e->e_ident[EI_MAG2] == ELFMAG2 &&
- e->e_ident[EI_MAG3] == ELFMAG3 &&
- e->e_ident[EI_CLASS] == ELFCLASS64 &&
- e->e_ident[EI_DATA] == ELFDATA2MSB &&
- e->e_type == ET_EXEC &&
- e->e_machine == EM_PPC64);
+ Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
+
+ return (e->e_ident[EI_MAG0] == ELFMAG0 &&
+ e->e_ident[EI_MAG1] == ELFMAG1 &&
+ e->e_ident[EI_MAG2] == ELFMAG2 &&
+ e->e_ident[EI_MAG3] == ELFMAG3 &&
+ e->e_ident[EI_CLASS] == ELFCLASS64 &&
+ e->e_ident[EI_DATA] == ELFDATA2MSB &&
+ e->e_type == ET_EXEC &&
+ e->e_machine == EM_PPC64);
}
static void
setup_display(void)
{
#ifdef CONFIG_SET_COLORMAP
- static unsigned char default_colors[] = {
- 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xaa,
- 0x00, 0xaa, 0x00,
- 0x00, 0xaa, 0xaa,
- 0xaa, 0x00, 0x00,
- 0xaa, 0x00, 0xaa,
- 0xaa, 0x55, 0x00,
- 0xaa, 0xaa, 0xaa,
- 0x55, 0x55, 0x55,
- 0x55, 0x55, 0xff,
- 0x55, 0xff, 0x55,
- 0x55, 0xff, 0xff,
- 0xff, 0x55, 0x55,
- 0xff, 0x55, 0xff,
- 0xff, 0xff, 0x55,
- 0xff, 0xff, 0xff
- };
- int i, result;
- prom_handle scrn = PROM_INVALID_HANDLE;
-
- /* Try Apple's mac-boot screen ihandle */
- result = (int)call_prom_return("interpret", 1, 2,
- "\" _screen-ihandle\" $find if execute else 0 then", &scrn);
- DEBUG_F("Trying to get screen ihandle, result: %d, scrn: %p\n", result, scrn);
-
- if (scrn == 0 || scrn == PROM_INVALID_HANDLE) {
- char type[32];
- /* Hrm... check to see if stdout is a display */
- scrn = call_prom ("instance-to-package", 1, 1, prom_stdout);
- DEBUG_F("instance-to-package of stdout is: %p\n", scrn);
- if (prom_getprop(scrn, "device_type", type, 32) > 0 && !strncmp(type, "display", 7)) {
- DEBUG_F("got it ! stdout is a screen\n");
- scrn = prom_stdout;
- } else {
- /* Else, we try to open the package */
- scrn = (prom_handle)call_prom( "open", 1, 1, "screen" );
- DEBUG_F("Open screen result: %p\n", scrn);
- }
- }
+ static unsigned char default_colors[] = {
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00,
+ 0x00, 0xaa, 0xaa,
+ 0xaa, 0x00, 0x00,
+ 0xaa, 0x00, 0xaa,
+ 0xaa, 0x55, 0x00,
+ 0xaa, 0xaa, 0xaa,
+ 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0xff,
+ 0x55, 0xff, 0x55,
+ 0x55, 0xff, 0xff,
+ 0xff, 0x55, 0x55,
+ 0xff, 0x55, 0xff,
+ 0xff, 0xff, 0x55,
+ 0xff, 0xff, 0xff
+ };
+ int i, result;
+ prom_handle scrn = PROM_INVALID_HANDLE;
+
+ /* Try Apple's mac-boot screen ihandle */
+ result = (int)call_prom_return("interpret", 1, 2,
+ "\" _screen-ihandle\" $find if execute else 0 then", &scrn);
+ DEBUG_F("Trying to get screen ihandle, result: %d, scrn: %p\n", result, scrn);
+
+ if (scrn == 0 || scrn == PROM_INVALID_HANDLE) {
+ char type[32];
+ /* Hrm... check to see if stdout is a display */
+ scrn = call_prom ("instance-to-package", 1, 1, prom_stdout);
+ DEBUG_F("instance-to-package of stdout is: %p\n", scrn);
+ if (prom_getprop(scrn, "device_type", type, 32) > 0 && !strncmp(type, "display", 7)) {
+ DEBUG_F("got it ! stdout is a screen\n");
+ scrn = prom_stdout;
+ } else {
+ /* Else, we try to open the package */
+ scrn = (prom_handle)call_prom( "open", 1, 1, "screen" );
+ DEBUG_F("Open screen result: %p\n", scrn);
+ }
+ }
- if (scrn == PROM_INVALID_HANDLE) {
- prom_printf("No screen device found !/n");
- return;
- }
- for(i=0;i<16;i++) {
- prom_set_color(scrn, i, default_colors[i*3],
- default_colors[i*3+1], default_colors[i*3+2]);
- }
- prom_printf("\x1b[1;37m\x1b[2;40m");
+ if (scrn == PROM_INVALID_HANDLE) {
+ prom_printf("No screen device found !/n");
+ return;
+ }
+ for(i=0;i<16;i++) {
+ prom_set_color(scrn, i, default_colors[i*3],
+ default_colors[i*3+1], default_colors[i*3+2]);
+ }
+ prom_printf("\x1b[1;37m\x1b[2;40m");
#ifdef COLOR_TEST
- for (i=0;i<16; i++) {
- prom_printf("\x1b[%d;%dm\x1b[1;47m%s \x1b[2;40m %s\n",
- ansi_color_table[i].index,
- ansi_color_table[i].value,
- ansi_color_table[i].name,
- ansi_color_table[i].name);
- prom_printf("\x1b[%d;%dm\x1b[1;37m%s \x1b[2;30m %s\n",
- ansi_color_table[i].index,
- ansi_color_table[i].value+10,
- ansi_color_table[i].name,
- ansi_color_table[i].name);
- }
- prom_printf("\x1b[1;37m\x1b[2;40m");
+ for (i=0;i<16; i++) {
+ prom_printf("\x1b[%d;%dm\x1b[1;47m%s \x1b[2;40m %s\n",
+ ansi_color_table[i].index,
+ ansi_color_table[i].value,
+ ansi_color_table[i].name,
+ ansi_color_table[i].name);
+ prom_printf("\x1b[%d;%dm\x1b[1;37m%s \x1b[2;30m %s\n",
+ ansi_color_table[i].index,
+ ansi_color_table[i].value+10,
+ ansi_color_table[i].name,
+ ansi_color_table[i].name);
+ }
+ prom_printf("\x1b[1;37m\x1b[2;40m");
#endif /* COLOR_TEST */
#if !DEBUG
- prom_printf("\xc");
+ prom_printf("\xc");
#endif /* !DEBUG */
#endif /* CONFIG_SET_COLORMAP */
*
* Usage: addnote zImage
*/
+
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define N_DESCR 6
unsigned int descr[N_DESCR] = {
- 0xffffffff, /* real-mode = true */
- 0x00c00000, /* real-base, i.e. where we expect OF to be */
- 0xffffffff, /* real-size */
- 0xffffffff, /* virt-base */
- 0xffffffff, /* virt-size */
- 0x4000, /* load-base */
+ 0xffffffff, /* real-mode = true */
+ 0x00c00000, /* real-base, i.e. where we expect OF to be */
+ 0xffffffff, /* real-size */
+ 0xffffffff, /* virt-base */
+ 0xffffffff, /* virt-size */
+ 0x4000, /* load-base */
};
unsigned char buf[512];
int
main(int ac, char **av)
{
- int fd, n, i;
- int ph, ps, np;
- int nnote, ns;
-
- if (ac != 2) {
- fprintf(stderr, "Usage: %s elf-file\n", av[0]);
- exit(1);
- }
- fd = open(av[1], O_RDWR);
- if (fd < 0) {
- perror(av[1]);
- exit(1);
- }
-
- nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
-
- n = read(fd, buf, sizeof(buf));
- if (n < 0) {
- perror("read");
- exit(1);
- }
-
- if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
- goto notelf;
-
- if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
- || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
- fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
- av[1]);
- exit(1);
- }
-
- ph = GET_32BE(E_PHOFF);
- ps = GET_16BE(E_PHENTSIZE);
- np = GET_16BE(E_PHNUM);
- if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
- goto notelf;
- if (ph + (np + 1) * ps + nnote > n)
- goto nospace;
-
- for (i = 0; i < np; ++i) {
- if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
- fprintf(stderr, "%s already has a note entry\n",
- av[1]);
- exit(0);
- }
- ph += ps;
- }
-
- /* XXX check that the area we want to use is all zeroes */
- for (i = 0; i < ps + nnote; ++i)
- if (buf[ph + i] != 0)
- goto nospace;
-
- /* fill in the program header entry */
- ns = ph + ps;
- PUT_32BE(ph + PH_TYPE, PT_NOTE);
- PUT_32BE(ph + PH_OFFSET, ns);
- PUT_32BE(ph + PH_FILESZ, nnote);
-
- /* fill in the note area we point to */
- /* XXX we should probably make this a proper section */
- PUT_32BE(ns, strlen(arch) + 1);
- PUT_32BE(ns + 4, N_DESCR * 4);
- PUT_32BE(ns + 8, 0x1275);
- strcpy(&buf[ns + 12], arch);
- ns += 12 + strlen(arch) + 1;
- for (i = 0; i < N_DESCR; ++i)
- PUT_32BE(ns + i * 4, descr[i]);
-
- /* Update the number of program headers */
- PUT_16BE(E_PHNUM, np + 1);
-
- /* write back */
- lseek(fd, (long) 0, SEEK_SET);
- i = write(fd, buf, n);
- if (i < 0) {
- perror("write");
- exit(1);
- }
- if (i < n) {
- fprintf(stderr, "%s: write truncated\n", av[1]);
- exit(1);
- }
-
- exit(0);
-
- notelf:
- fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
- exit(1);
-
- nospace:
- fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
- av[1]);
- exit(1);
+ int fd, n, i;
+ int ph, ps, np;
+ int nnote, ns;
+
+ if (ac != 2) {
+ fprintf(stderr, "Usage: %s elf-file\n", av[0]);
+ exit(1);
+ }
+ fd = open(av[1], O_RDWR);
+ if (fd < 0) {
+ perror(av[1]);
+ exit(1);
+ }
+
+ nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n < 0) {
+ perror("read");
+ exit(1);
+ }
+
+ if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
+ goto notelf;
+
+ if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
+ || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
+ fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
+ av[1]);
+ exit(1);
+ }
+
+ ph = GET_32BE(E_PHOFF);
+ ps = GET_16BE(E_PHENTSIZE);
+ np = GET_16BE(E_PHNUM);
+ if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
+ goto notelf;
+ if (ph + (np + 1) * ps + nnote > n)
+ goto nospace;
+
+ for (i = 0; i < np; ++i) {
+ if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
+ fprintf(stderr, "%s already has a note entry\n",
+ av[1]);
+ exit(0);
+ }
+ ph += ps;
+ }
+
+ /* XXX check that the area we want to use is all zeroes */
+ for (i = 0; i < ps + nnote; ++i)
+ if (buf[ph + i] != 0)
+ goto nospace;
+
+ /* fill in the program header entry */
+ ns = ph + ps;
+ PUT_32BE(ph + PH_TYPE, PT_NOTE);
+ PUT_32BE(ph + PH_OFFSET, ns);
+ PUT_32BE(ph + PH_FILESZ, nnote);
+
+ /* fill in the note area we point to */
+ /* XXX we should probably make this a proper section */
+ PUT_32BE(ns, strlen(arch) + 1);
+ PUT_32BE(ns + 4, N_DESCR * 4);
+ PUT_32BE(ns + 8, 0x1275);
+ strcpy(&buf[ns + 12], arch);
+ ns += 12 + strlen(arch) + 1;
+ for (i = 0; i < N_DESCR; ++i)
+ PUT_32BE(ns + i * 4, descr[i]);
+
+ /* Update the number of program headers */
+ PUT_16BE(E_PHNUM, np + 1);
+
+ /* write back */
+ lseek(fd, (long) 0, SEEK_SET);
+ i = write(fd, buf, n);
+ if (i < 0) {
+ perror("write");
+ exit(1);
+ }
+ if (i < n) {
+ fprintf(stderr, "%s: write truncated\n", av[1]);
+ exit(1);
+ }
+
+ exit(0);
+
+notelf:
+ fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]);
+ exit(1);
+
+nospace:
+ fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
+ av[1]);
+ exit(1);
}
+
+/*
+ * Local variables:
+ * c-file-style: "K&R"
+ * c-basic-offset: 5
+ * End:
+ */
fi
PRG="${0##*/}"
SIGINT="$PRG: Interrupt caught ... exiting"
-VERSION=1.3.4pre3
+VERSION=1.3.4
DEBUG=0
VERBOSE=0
TMP="${TMPDIR:-/tmp}"