diff options
Diffstat (limited to 'sys/boot/sparc64/boot1/boot1.c')
-rw-r--r-- | sys/boot/sparc64/boot1/boot1.c | 159 |
1 files changed, 109 insertions, 50 deletions
diff --git a/sys/boot/sparc64/boot1/boot1.c b/sys/boot/sparc64/boot1/boot1.c index db6a807..d575775 100644 --- a/sys/boot/sparc64/boot1/boot1.c +++ b/sys/boot/sparc64/boot1/boot1.c @@ -35,46 +35,54 @@ __FBSDID("$FreeBSD$"); #define BSIZEMAX 8192 -/* - * This structure will be refined along with the addition of a bootpath - * parsing routine when it is necessary to cope with bootpaths that are - * not in the exact <devpath>@<controller>,<disk>:<partition> format and - * for which we need to evaluate the disklabel ourselves. - */ -struct disk { - int meta; +typedef int putc_func_t(int c, void *arg); +typedef int32_t ofwh_t; + +struct sp_data { + char *sp_buf; + u_int sp_len; + u_int sp_size; }; -struct disk dsk; static const char digits[] = "0123456789abcdef"; static char bootpath[128]; static char bootargs[128]; -static int kflag; +static ofwh_t bootdev; -static uint32_t fs_off; +static struct fs fs; +static ino_t inomap; +static char blkbuf[BSIZEMAX]; +static unsigned int fsblks; -typedef int putc_func_t(int c, void *arg); +static uint32_t fs_off; int main(int ac, char **av); -static void exit(int); +static void exit(int) __dead2; static void load(const char *); static ino_t lookup(const char *); static ssize_t fsread(ino_t, void *, size_t); static int dskread(void *, u_int64_t, int); +static void usage(void); + static void bcopy(const void *src, void *dst, size_t len); static void bzero(void *b, size_t len); +static int mount(const char *device); + +static void panic(const char *fmt, ...) __dead2; static int printf(const char *fmt, ...); -static int vprintf(const char *fmt, va_list ap); static int putchar(int c, void *arg); +static int vprintf(const char *fmt, va_list ap); +static int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap); static int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap); static int __putc(int c, void *arg); static int __puts(const char *s, putc_func_t *putc, void *arg); +static int __sputc(int c, void *arg); static char *__uitoa(char *buf, u_int val, int base); static char *__ultoa(char *buf, u_long val, int base); @@ -82,7 +90,6 @@ static char *__ultoa(char *buf, u_long val, int base); * Open Firmware interface functions */ typedef u_int64_t ofwcell_t; -typedef int32_t ofwh_t; typedef u_int32_t u_ofwh_t; typedef int (*ofwfp_t)(ofwcell_t []); ofwfp_t ofw; /* the prom Open Firmware entry */ @@ -94,6 +101,7 @@ int ofw_getprop(ofwh_t, const char *, void *, size_t); int ofw_read(ofwh_t, void *, size_t); int ofw_write(ofwh_t, const void *, size_t); int ofw_seek(ofwh_t, u_int64_t); +void ofw_exit(void) __dead2; ofwh_t bootdevh; ofwh_t stdinh, stdouth; @@ -122,10 +130,6 @@ ofw_init(int d, int d1, int d2, int d3, ofwfp_t ofwaddr) bootargs[sizeof(bootargs) - 1] = '\0'; bootpath[sizeof(bootpath) - 1] = '\0'; - if ((bootdevh = ofw_open(bootpath)) == -1) { - printf("Could not open boot device.\n"); - } - ac = 0; p = bootargs; for (;;) { @@ -287,7 +291,8 @@ ofw_exit(void) args[1] = 0; args[2] = 0; - (*ofw)(args); + for (;;) + (*ofw)(args); } static void @@ -350,11 +355,8 @@ main(int ac, char **av) switch (av[i][0]) { case '-': switch (av[i][1]) { - case 'k': - kflag = 1; - break; default: - break; + usage(); } break; default: @@ -366,17 +368,51 @@ main(int ac, char **av) printf(" \n>> FreeBSD/sparc64 boot block\n" " Boot path: %s\n" " Boot loader: %s\n", bootpath, path); + + if (mount(bootpath) == -1) + panic("mount"); + load(path); return (1); } static void +usage(void) +{ + + printf("usage: boot device [/path/to/loader]\n"); + exit(1); +} + +static void exit(int code) { ofw_exit(); } +static int +mount(const char *device) +{ + + if ((bootdev = ofw_open(device)) == -1) { + printf("mount: can't open device\n"); + return (-1); + } + if (dskread(blkbuf, SBOFF / DEV_BSIZE, SBSIZE / DEV_BSIZE)) { + printf("mount: can't read superblock\n"); + return (-1); + } + inomap = 0; + bcopy(blkbuf, &fs, sizeof(fs)); + if (fs.fs_magic != FS_MAGIC) { + printf("mount: not ufs\n"); + return (-1); + } + fsblks = fs.fs_bsize >> DEV_BSHIFT; + return (0); +} + static void load(const char *fname) { @@ -415,7 +451,7 @@ load(const char *fname) if (ph.p_filesz != ph.p_memsz) bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz); } - ofw_close(bootdevh); + ofw_close(bootdev); (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw); } @@ -457,29 +493,13 @@ lookup(const char *path) static ssize_t fsread(ino_t inode, void *buf, size_t nbyte) { - static struct fs fs; static struct dinode din; - static char blkbuf[BSIZEMAX]; static ufs_daddr_t indbuf[BSIZEMAX / sizeof(ufs_daddr_t)]; - static ino_t inomap; static ufs_daddr_t blkmap, indmap; - static unsigned int fsblks; char *s; ufs_daddr_t lbn, addr; size_t n, nb, off; - if (!dsk.meta) { - inomap = 0; - if (dskread(blkbuf, SBOFF / DEV_BSIZE, SBSIZE / DEV_BSIZE)) - return (-1); - bcopy(blkbuf, &fs, sizeof(fs)); - if (fs.fs_magic != FS_MAGIC) { - printf("Not ufs\n"); - return (-1); - } - fsblks = fs.fs_bsize >> DEV_BSHIFT; - dsk.meta++; - } if (!inode) return (0); if (inomap != inode) { @@ -537,29 +557,34 @@ dskread(void *buf, u_int64_t lba, int nblk) * That means, if we read from offset zero on an open instance handle, * we should read from offset zero of that partition. */ - ofw_seek(bootdevh, lba * DEV_BSIZE); - ofw_read(bootdevh, buf, nblk * DEV_BSIZE); + ofw_seek(bootdev, lba * DEV_BSIZE); + ofw_read(bootdev, buf, nblk * DEV_BSIZE); return (0); } -static int -printf(const char *fmt, ...) +static void +panic(const char *fmt, ...) { + char buf[128]; va_list ap; - int ret; va_start(ap, fmt); - ret = vprintf(fmt, ap); + vsnprintf(buf, sizeof buf, fmt, ap); + printf("panic: %s\n", buf); va_end(ap); - return (ret); + + exit(1); } static int -vprintf(const char *fmt, va_list ap) +printf(const char *fmt, ...) { + va_list ap; int ret; - ret = __printf(fmt, putchar, 0, ap); + va_start(ap, fmt); + ret = vprintf(fmt, ap); + va_end(ap); return (ret); } @@ -578,6 +603,28 @@ putchar(int c, void *arg) } static int +vprintf(const char *fmt, va_list ap) +{ + int ret; + + ret = __printf(fmt, putchar, 0, ap); + return (ret); +} + +static int +vsnprintf(char *str, size_t sz, const char *fmt, va_list ap) +{ + struct sp_data sp; + int ret; + + sp.sp_buf = str; + sp.sp_len = 0; + sp.sp_size = sz; + ret = __printf(fmt, __sputc, &sp, ap); + return (ret); +} + +static int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap) { char buf[(sizeof(long) * 8) + 1]; @@ -688,6 +735,18 @@ reswitch: c = *fmt++; } static int +__sputc(int c, void *arg) +{ + struct sp_data *sp; + + sp = arg; + if (sp->sp_len < sp->sp_size) + sp->sp_buf[sp->sp_len++] = c; + sp->sp_buf[sp->sp_len] = '\0'; + return (1); +} + +static int __puts(const char *s, putc_func_t *putc, void *arg) { const char *p; |