boot1.c revision 199767f8919635c4928607450d9e0abb932109ce
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Robert Nordier
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 2001 Robert Drehmel
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms are freely
199767f8919635c4928607450d9e0abb932109ceToomas Soome * permitted provided that the above copyright notice and this
199767f8919635c4928607450d9e0abb932109ceToomas Soome * paragraph and the following disclaimer are duplicated in all
199767f8919635c4928607450d9e0abb932109ceToomas Soome * such forms.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This software is provided "AS IS" and without any express or
199767f8919635c4928607450d9e0abb932109ceToomas Soome * implied warranties, including, without limitation, the implied
199767f8919635c4928607450d9e0abb932109ceToomas Soome * warranties of merchantability and fitness for a particular
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic const char digits[] = "0123456789abcdef";
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void usage(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void loadzfs(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int zbread(char *buf, off_t off, size_t bytes);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void load(const char *);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void bcopy(const void *src, void *dst, size_t len);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int dskread(void *buf, u_int64_t lba, int nblk);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void panic(const char *fmt, ...) __dead2;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int vprintf(const char *fmt, va_list ap);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int __puts(const char *s, putc_func_t *putc, void *arg);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char *__uitoa(char *buf, u_int val, int base);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char *__ultoa(char *buf, u_long val, int base);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Open Firmware interface functions
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic ofwfp_t ofw; /* the PROM Open Firmware entry */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int ofw_getprop(ofwh_t, const char *, void *, size_t);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int ofw_write(ofwh_t, const void *, size_t);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This has to stay here, as the PROM seems to ignore the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * entry point specified in the a.out header. (or elftoaout is broken)
199767f8919635c4928607450d9e0abb932109ceToomas Soomeofw_init(int d, int d1, int d2, int d3, ofwfp_t ofwaddr)
199767f8919635c4928607450d9e0abb932109ceToomas Soome ofw_getprop(chosenh, "stdin", &stdinh, sizeof(stdinh));
199767f8919635c4928607450d9e0abb932109ceToomas Soome ofw_getprop(chosenh, "stdout", &stdouth, sizeof(stdouth));
199767f8919635c4928607450d9e0abb932109ceToomas Soome ofw_getprop(chosenh, "bootargs", bootargs, sizeof(bootargs));
199767f8919635c4928607450d9e0abb932109ceToomas Soome ofw_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath));
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (*p != '\0')
199767f8919635c4928607450d9e0abb932109ceToomas Soome *p++ = '\0';
199767f8919635c4928607450d9e0abb932109ceToomas Soomeofw_getprop(ofwh_t ofwh, const char *name, void *buf, size_t len)
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("ofw_getprop: ofwh=0x%x buf=%p len=%u\n",
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("ofw_read: devh=0x%x buf=%p len=%u\n", devh, buf, len);
199767f8919635c4928607450d9e0abb932109ceToomas Soomeofw_write(ofwh_t devh, const void *buf, size_t len)
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("ofw_write: devh=0x%x buf=%p len=%u\n", devh, buf, len);
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("ofw_seek: devh=0x%x off=0x%lx\n", devh, off);
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *s = src;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (len-- != 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome *d++ = *s++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *p = b;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (len-- != 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *path;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < ac; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome switch (av[i][0]) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf(" \n>> FreeBSD/sparc64 ZFS boot block\n Boot path: %s\n",
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf(" \n>> FreeBSD/sparc64 boot block\n Boot path: %s\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("usage: boot device [/path/to/loader]\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned int nb;
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned int lb;
199767f8919635c4928607450d9e0abb932109ceToomas Soome lb = (soff + bytes + DEV_BSIZE - 1) / DEV_BSIZE;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((poff / DEV_BSIZE + nb) * DEV_BSIZE > soff + bytes)
199767f8919635c4928607450d9e0abb932109ceToomas Soome len = (poff / DEV_BSIZE + nb) * DEV_BSIZE - poff;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (zbread((char *)&eh, 0, sizeof(eh)) != sizeof(eh)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (zbread((char *)&ph, fs_off, sizeof(ph)) != sizeof(ph)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (zbread(p, fs_off, ph.p_filesz) != ph.p_filesz) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Can't read content of section %d\n", i);
199767f8919635c4928607450d9e0abb932109ceToomas Soome bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fsread(ino, &eh, sizeof(eh)) != sizeof(eh)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fsread(ino, &ph, sizeof(ph)) != sizeof(ph)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fsread(ino, p, ph.p_filesz) != ph.p_filesz) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Can't read content of section %d\n", i);
199767f8919635c4928607450d9e0abb932109ceToomas Soome bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz);
199767f8919635c4928607450d9e0abb932109ceToomas Soome (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif /* ZFSBOOT */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The Open Firmware should open the correct partition for us.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * That means, if we read from offset zero on an open instance handle,
199767f8919635c4928607450d9e0abb932109ceToomas Soome * we should read from offset zero of that partition.
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (c == '\n') {
199767f8919635c4928607450d9e0abb932109ceToomas Soomevsnprintf(char *str, size_t sz, const char *fmt, va_list ap)
199767f8919635c4928607450d9e0abb932109ceToomas Soome__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap)
199767f8919635c4928607450d9e0abb932109ceToomas Soome while ((c = *fmt++) != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (c != '%') {
199767f8919635c4928607450d9e0abb932109ceToomas Soome switch (c) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '0': case '1': case '2': case '3': case '4':
199767f8919635c4928607450d9e0abb932109ceToomas Soome case '5': case '6': case '7': case '8': case '9':
199767f8919635c4928607450d9e0abb932109ceToomas Soome__puts(const char *s, putc_func_t *putc, void *arg)
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *p;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (p = s; *p != '\0'; p++)
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char *
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic char *