On Mon, Sep 25, 2023 at 05:35:40AM +0000, Visa Hankala wrote: > On Sat, Sep 23, 2023 at 02:26:18PM +0000, Klemens Nanni wrote: > > On Sat, Sep 23, 2023 at 01:11:32PM +0200, Mark Kettenis wrote: > > > > Date: Thu, 21 Sep 2023 22:30:01 +0000 > > > > From: Klemens Nanni <k...@openbsd.org> > > > > > > > > In comparison to MI boot which only cares about /bsd.upgrade's x bit, > > > > powerpc64 rdboot just wants a regular file. > > > > > > > > Require and strip u+x before execution to prevent sysupgrade(8) loop. > > > > I'm new to powerpc64 and can't think of a reason to be different. > > > > > > > > Feedback? Objection? OK? > > > > > > So there is a problem with this approach. Calling chmod() will mean > > > the bootloader will change the filesystem. What happens if you're > > > booting with a root filesystem that was not cleanly unmounted? > > > Modifying a forcibly mounted filesystem may not be without risk. > > > > Isn't that already the case with chmo() /etc/random.seed? > > > > Can you explain how that is not a problem in other non-kernel boot loaders > > using libsa's ufs2_open() instead of mount(2)? > > chmod() through libsa's filesystem code modifies only the inode. > Doing a mount-chmod-unmount cycle using the kernel triggers multiple > writes to the filesystem. > > In the past, I have pondered if octeon (and powerpc64) bootcode should > use libsa instead of replicating the MI boot code. I did not use libsa > initially because the libsa and libc APIs differ, and I did not want > to use custom system call stubs. The original octboot/kexec interface > was not suitable for libsa use, either.
Are there more reasons or benefits to this approach than a) less intrusive chmod() and b) more shared, overall less code? I obviously don't see the full picture (yet). > However, the libsa and libc worlds can be reconciled with a trick. > The libsa code is first compiled in standalone mode into a relinkable > object ("saboot"). This object is then tweaked to avoid name conflicts > with libc. Finally, the object is linked with glue code and libc into > a proper rdboot executable that the kernel can run. > > Some have seen this before. > > > diff --git a/sys/arch/octeon/stand/Makefile b/sys/arch/octeon/stand/Makefile > index 498bd2809c6..4a86a8bef6b 100644 > --- a/sys/arch/octeon/stand/Makefile > +++ b/sys/arch/octeon/stand/Makefile > @@ -1,5 +1,5 @@ > # $OpenBSD: Makefile,v 1.4 2019/08/04 08:53:14 visa Exp $ > > -SUBDIR+= rdboot boot > +SUBDIR+= saboot rdboot boot > > .include <bsd.subdir.mk> > diff --git a/sys/arch/octeon/stand/Makefile.inc > b/sys/arch/octeon/stand/Makefile.inc > deleted file mode 100644 > index 18d8470f888..00000000000 > --- a/sys/arch/octeon/stand/Makefile.inc > +++ /dev/null > @@ -1,45 +0,0 @@ > -# $OpenBSD: Makefile.inc,v 1.1 2013/06/05 01:02:29 jasper Exp $ > - > -BINDIR= /usr/mdec > - > -STANDALONE?= -D_STANDALONE > - > -.if ${MACHINE} == "octeon" > -CPPFLAGS+= ${STANDALONE} > -CPPFLAGS+= -I. > -CFLAGS+= -fno-stack-protector -Wall > -CFLAGS+= -fno-builtin-vprintf -fno-builtin-printf -fno-builtin-putchar > -# Silence warnings > -CFLAGS+= -fno-builtin-snprintf > -CFLAGS+= -fno-builtin-memcpy > -CFLAGS+= -fno-builtin-memcmp > -CFLAGS+= -fno-builtin-memset > -CFLAGS+= -fno-builtin-strncpy > -CFLAGS+= -fno-builtin-strncmp > -CFLAGS+= -fno-builtin-exit > -SAABI= -mips3 -mno-abicalls -G 0 -fno-pic -fno-common > -AS?= as > -LD?= ld > -.endif > - > -### Figure out what to use for libsa > -LIBSADIR?= ${.CURDIR}/../libsa > - > -.if exists(${LIBSADIR}/${__objdir}) > -LIBSAOBJDIR= ${LIBSADIR}/${__objdir} > -.else > -LIBSAOBJDIR= ${LIBSADIR} > -.endif > - > -LIBSA= ${LIBSAOBJDIR}/libsa.a > - > -### Figure out what to use for libz > -LIBZDIR?= ${.CURDIR}/../libz > - > -.if exists(${LIBZDIR}/${__objdir}) > -LIBZOBJDIR= ${LIBZDIR}/${__objdir} > -.else > -LIBZOBJDIR= ${LIBZDIR} > -.endif > - > -LIBZ= ${LIBZOBJDIR}/libz.a > diff --git a/sys/arch/octeon/stand/libsa/Makefile > b/sys/arch/octeon/stand/libsa/Makefile > deleted file mode 100644 > index 3b2961f25c0..00000000000 > --- a/sys/arch/octeon/stand/libsa/Makefile > +++ /dev/null > @@ -1,51 +0,0 @@ > -# $OpenBSD: Makefile,v 1.8 2019/10/29 02:55:52 deraadt Exp $ > - > -.include "${.CURDIR}/../Makefile.inc" > - > -LIB= sa > - > -.PATH: ${.CURDIR}/../../../../lib/libsa > - > -CLEANFILES += machine mips64 > - > -CFLAGS+= ${CEXTRAFLAGS} ${SAABI} -nostdinc -mno-abicalls -D_NO_ABICALLS \ > - -fno-pie \ > - -I${.CURDIR} -I${.CURDIR}/../include -I${.CURDIR}/../.. \ > - -I${.CURDIR}/../../.. -I${.CURDIR}/../../../.. \ > - -I${.CURDIR}/../../../../lib/libsa \ > - -I${.OBJDIR} > - > -# stand routines > -SRCS= alloc.c cons.c ctime.c exit.c getchar.c getfile.c getln.c > globals.c \ > - memcmp.c memcpy.c memmove.c memset.c printf.c putchar.c \ > - snprintf.c strchr.c strcmp.c strerror.c strncmp.c strncpy.c strtol.c > - > -# io routines > -SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c fstat.c ioctl.c \ > - lseek.c open.c read.c readdir.c stat.c write.c > - > -#SRCS+= cread.c > -#CPPFLAGS+= -D__INTERNAL_LIBSA_CREAD > - > -# boot filesystems > -SRCS+= ufs.c cd9660.c > - > -CFLAGS+=-DNO_NET > - > -SRCS+= loadfile.c arc4.c > - > -${OBJS}: ${.CURDIR}/../Makefile.inc > - > -NOPROFILE= > -NOPIC= > - > -.if !make(clean) && !make(cleandir) && !make(includes) && !make(obj) > -.BEGIN: > - @([ -h machine ] || ln -s ${.CURDIR}/../../include machine) > - @([ -h mips64 ] || ln -s ${.CURDIR}/../../../mips64/include mips64) > -CLEANFILES+= machine mips64 > -.endif > - > -install: > - > -.include <bsd.lib.mk> > diff --git a/sys/arch/octeon/stand/rdboot/Makefile > b/sys/arch/octeon/stand/rdboot/Makefile > index 841c363ed60..5833076c30b 100644 > --- a/sys/arch/octeon/stand/rdboot/Makefile > +++ b/sys/arch/octeon/stand/rdboot/Makefile > @@ -4,16 +4,32 @@ NOMAN= > > .if ${MACHINE} == "octeon" > PROG= rdboot > -SRCS= cmd.c disk.c rdboot.c vars.c > -LDADD+= -lutil > -LDSTATIC+= -static > -.else > -NOPROG= > -.endif > > -.PATH: ${S}/lib/libsa > -#SRCS+= hexdump.c strtoll.c > +S= ${.CURDIR}/../../../.. > +BOOTDIR= ${S}/arch/octeon/stand/rdboot > + > +CFLAGS+= -Wall > +CFLAGS+= -I${.CURDIR}/../saboot > + > +.PATH: ${BOOTDIR} > +SRCS= rdboot.c unixcall.c > > install: > > +.if !make(clean) && !make(cleandir) && !make(includes) && !make(obj) > +.BEGIN: > + @([ -h machine ] || ln -s ${.CURDIR}/../../include machine) > + @([ -h mips64 ] || ln -s ${.CURDIR}/../../../mips64/include mips64) > +CLEANFILES+= machine mips64 > +.endif > + > +SABOOT= ${.CURDIR}/../saboot/obj/saboot.elf > + > +${PROG}: ${OBJS} ${SABOOT} > + ${CC} -static -o $@ ${SABOOT} ${OBJS} -lutil > + > +.else > +NOPROG= > +.endif > + > .include <bsd.prog.mk> > diff --git a/sys/arch/octeon/stand/rdboot/cmd.c > b/sys/arch/octeon/stand/rdboot/cmd.c > deleted file mode 100644 > index c9790bb8920..00000000000 > --- a/sys/arch/octeon/stand/rdboot/cmd.c > +++ /dev/null > @@ -1,507 +0,0 @@ > -/* $OpenBSD: cmd.c,v 1.3 2019/08/01 04:52:56 visa Exp $ */ > - > -/* > - * Copyright (c) 1997-1999 Michael Shalayeff > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or without > - * modification, are permitted provided that the following conditions > - * are met: > - * 1. Redistributions of source code must retain the above copyright > - * notice, this list of conditions and the following disclaimer. > - * 2. Redistributions in binary form must reproduce the above copyright > - * notice, this list of conditions and the following disclaimer in the > - * documentation and/or other materials provided with the distribution. > - * > - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE > - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > - * SUCH DAMAGE. > - */ > - > -#include <sys/param.h> > -#include <sys/reboot.h> > -#include <sys/select.h> > -#include <sys/stat.h> > - > -#include <dirent.h> > -#include <errno.h> > -#include <fcntl.h> > -#include <stdio.h> > -#include <string.h> > -#include <termios.h> > -#include <unistd.h> > - > -#include "cmd.h" > -#include "disk.h" > - > -static int Xboot(void); > -static int Xecho(void); > -static int Xhelp(void); > -static int Xls(void); > -static int Xnop(void); > -static int Xreboot(void); > -#ifdef MACHINE_CMD > -static int Xmachine(void); > -extern const struct cmd_table MACHINE_CMD[]; > -#endif > -extern int Xset(void); > - > -#ifdef CHECK_SKIP_CONF > -extern int CHECK_SKIP_CONF(void); > -#endif > - > -extern const struct cmd_table cmd_set[]; > -const struct cmd_table cmd_table[] = { > - {"#", CMDT_CMD, Xnop}, /* XXX must be first */ > - {"boot", CMDT_CMD, Xboot}, > - {"echo", CMDT_CMD, Xecho}, > - {"help", CMDT_CMD, Xhelp}, > - {"ls", CMDT_CMD, Xls}, > -#ifdef MACHINE_CMD > - {"machine",CMDT_MDC, Xmachine}, > -#endif > - {"reboot", CMDT_CMD, Xreboot}, > - {"set", CMDT_SET, Xset}, > - {NULL, 0}, > -}; > - > -static void ls(const char *, struct stat *); > -static int readline(char *, size_t, int); > -char *nextword(char *); > -static char *whatcmd(const struct cmd_table **ct, char *); > -static char *qualify(char *); > - > -char cmd_buf[CMD_BUFF_SIZE]; > - > -int > -getcmd(void) > -{ > - cmd.cmd = NULL; > - > - if (!readline(cmd_buf, sizeof(cmd_buf), cmd.timeout)) > - cmd.cmd = cmd_table; > - > - return docmd(); > -} > - > -int > -read_conf(void) > -{ > - struct stat sb; > - const char *path; > - int fd, rc = 0; > - > -#ifdef CHECK_SKIP_CONF > - if (CHECK_SKIP_CONF()) { > - printf("boot.conf processing skipped at operator request\n"); > - cmd.timeout = 0; > - return -1; /* Pretend file wasn't found */ > - } > -#endif > - > - path = disk_open(qualify(cmd.conf)); > - if (path == NULL) { > - fprintf(stderr, "cannot open device for reading %s: %s\n", > - cmd.conf, strerror(errno)); > - return -1; > - } > - if ((fd = open(path, O_RDONLY)) == -1) { > - if (errno != ENOENT && errno != ENXIO) { > - fprintf(stderr, "%s: open(%s): %s\n", __func__, > - cmd.path, strerror(errno)); > - rc = 0; > - } else > - rc = -1; > - goto out; > - } > - > - (void) fstat(fd, &sb); > - if (sb.st_uid || (sb.st_mode & 2)) { > - fprintf(stderr, "non-secure %s, will not proceed\n", cmd.path); > - rc = -1; > - goto out; > - } > - > - do { > - char *p = cmd_buf; > - > - cmd.cmd = NULL; > - do { > - rc = read(fd, p, 1); > - } while (rc > 0 && *p++ != '\n' && > - (p-cmd_buf) < sizeof(cmd_buf)); > - > - if (rc < 0) { /* Error from read() */ > - fprintf(stderr, "%s: %s\n", cmd.path, strerror(errno)); > - break; > - } > - > - if (rc == 0) { /* eof from read() */ > - if (p != cmd_buf) { /* Line w/o trailing \n */ > - *p = '\0'; > - rc = docmd(); > - break; > - } > - } else { /* rc > 0, read a char */ > - p--; /* Get back to last character */ > - > - if (*p != '\n') { /* Line was too long */ > - fprintf(stderr, "%s: line too long\n", > - cmd.path); > - > - /* Don't want to run the truncated command */ > - rc = -1; > - } > - *p = '\0'; > - } > - } while (rc > 0 && !(rc = docmd())); > - > -out: > - if (fd != -1) > - close(fd); > - disk_close(); > - return rc; > -} > - > -int > -docmd(void) > -{ > - char *p = NULL; > - const struct cmd_table *ct = cmd_table, *cs; > - > - cmd.argc = 1; > - if (cmd.cmd == NULL) { > - > - /* command */ > - for (p = cmd_buf; *p == ' ' || *p == '\t'; p++) > - ; > - if (*p == '#' || *p == '\0') { /* comment or empty string */ > -#ifdef DEBUG > - printf("rem\n"); > -#endif > - return 0; > - } > - ct = cmd_table; > - cs = NULL; > - cmd.argv[cmd.argc] = p; /* in case it's shortcut boot */ > - p = whatcmd(&ct, p); > - if (ct == NULL) { > - cmd.argc++; > - ct = cmd_table; > - } else if (ct->cmd_type == CMDT_SET && p != NULL) { > - cs = cmd_set; > -#ifdef MACHINE_CMD > - } else if (ct->cmd_type == CMDT_MDC && p != NULL) { > - cs = MACHINE_CMD; > -#endif > - } > - > - if (cs != NULL) { > - p = whatcmd(&cs, p); > - if (cs == NULL) { > - printf("%s: syntax error\n", ct->cmd_name); > - return 0; > - } > - ct = cs; > - } > - cmd.cmd = ct; > - } > - > - cmd.argv[0] = ct->cmd_name; > - while (p && cmd.argc+1 < sizeof(cmd.argv) / sizeof(cmd.argv[0])) { > - cmd.argv[cmd.argc++] = p; > - p = nextword(p); > - } > - cmd.argv[cmd.argc] = NULL; > - > - return (*cmd.cmd->cmd_exec)(); > -} > - > -static char * > -whatcmd(const struct cmd_table **ct, char *p) > -{ > - char *q; > - int l; > - > - q = nextword(p); > - > - for (l = 0; p[l]; l++) > - ; > - > - while ((*ct)->cmd_name != NULL && strncmp(p, (*ct)->cmd_name, l)) > - (*ct)++; > - > - if ((*ct)->cmd_name == NULL) > - *ct = NULL; > - > - return q; > -} > - > -static int > -readline(char *buf, size_t n, int to) > -{ > - struct termios saved_tio, tio; > - struct timeval tv; > - fd_set fdset; > - char *p; > - int timed_out = 0; > -#ifdef DEBUG > - extern int debug; > -#endif > - > - /* Only do timeout if greater than 0 */ > - if (to > 0) { > - /* Switch to non-canonical mode for timeout detection. */ > - tcgetattr(STDIN_FILENO, &saved_tio); > - tio = saved_tio; > - tio.c_lflag &= ~(ECHO | ICANON); > - tcsetattr(STDIN_FILENO, TCSANOW, &tio); > - > - FD_ZERO(&fdset); > - FD_SET(STDIN_FILENO, &fdset); > - tv.tv_sec = to; > - tv.tv_usec = 0; > - if (select(STDIN_FILENO + 1, &fdset, NULL, NULL, &tv) == 0) > - timed_out = 1; > - > - /* Restore canonical mode. */ > - tcsetattr(STDIN_FILENO, TCSANOW, &saved_tio); > - > - if (timed_out) { > - strlcpy(buf, "boot", 5); > - putchar('\n'); > - return strlen(buf); > - } > - } > - > - /* User has typed something. Turn off timeouts. */ > - cmd.timeout = 0; > - > - if (fgets(buf, n, stdin) == NULL) > - return 0; > - > - /* Strip trailing newline. */ > - p = strchr(buf, '\n'); > - if (p != NULL) > - *p = '\0'; > - > - return strlen(buf); > -} > - > -/* > - * Search for spaces/tabs after the current word. If found, \0 the > - * first one. Then pass a pointer to the first character of the > - * next word, or NULL if there is no next word. > - */ > -char * > -nextword(char *p) > -{ > - /* skip blanks */ > - while (*p && *p != '\t' && *p != ' ') > - p++; > - if (*p) { > - *p++ = '\0'; > - while (*p == '\t' || *p == ' ') > - p++; > - } > - if (*p == '\0') > - p = NULL; > - return p; > -} > - > -static void > -print_help(const struct cmd_table *ct) > -{ > - for (; ct->cmd_name != NULL; ct++) > - printf(" %s", ct->cmd_name); > - putchar('\n'); > -} > - > -static int > -Xhelp(void) > -{ > - printf("commands:"); > - print_help(cmd_table); > -#ifdef MACHINE_CMD > - return Xmachine(); > -#else > - return 0; > -#endif > -} > - > -#ifdef MACHINE_CMD > -static int > -Xmachine(void) > -{ > - printf("machine:"); > - print_help(MACHINE_CMD); > - return 0; > -} > -#endif > - > -static int > -Xecho(void) > -{ > - int i; > - > - for (i = 1; i < cmd.argc; i++) > - printf("%s ", cmd.argv[i]); > - putchar('\n'); > - return 0; > -} > - > -static int > -Xls(void) > -{ > - struct stat sb; > - const char *path; > - DIR *dir; > - struct dirent *dent; > - int dirfd, oldcwd; > - > - path = disk_open(qualify(cmd.argv[1] ? cmd.argv[1] : "/.")); > - if (path == NULL) > - return 0; > - > - if (stat(path, &sb) < 0) { > - printf("stat(%s): %s\n", cmd.path, strerror(errno)); > - goto out; > - } > - > - if ((sb.st_mode & S_IFMT) != S_IFDIR) > - ls(path, &sb); > - else { > - oldcwd = open(".", O_RDONLY); > - > - dirfd = open(path, O_RDONLY); > - if (dirfd < 0) { > - printf("opendir(%s): %s\n", cmd.path, strerror(errno)); > - close(oldcwd); > - goto out; > - } > - if ((dir = fdopendir(dirfd)) < 0) { > - printf("opendir(%s): %s\n", cmd.path, strerror(errno)); > - close(dirfd); > - close(oldcwd); > - goto out; > - } > - fchdir(dirfd); > - while ((dent = readdir(dir)) != NULL) { > - if (fstatat(dirfd, dent->d_name, &sb, > - AT_SYMLINK_NOFOLLOW) < 0) > - printf("stat(%s): %s\n", dent->d_name, > - strerror(errno)); > - else > - ls(dent->d_name, &sb); > - } > - closedir(dir); > - > - fchdir(oldcwd); > - close(oldcwd); > - } > - > -out: > - disk_close(); > - return 0; > -} > - > -#define lsrwx(mode,s) \ > - putchar ((mode) & S_IROTH? 'r' : '-'); \ > - putchar ((mode) & S_IWOTH? 'w' : '-'); \ > - putchar ((mode) & S_IXOTH? *(s): (s)[1]); > - > -static void > -ls(const char *name, struct stat *sb) > -{ > - putchar("-fc-d-b---l-s-w-"[(sb->st_mode & S_IFMT) >> 12]); > - lsrwx(sb->st_mode >> 6, (sb->st_mode & S_ISUID? "sS" : "x-")); > - lsrwx(sb->st_mode >> 3, (sb->st_mode & S_ISGID? "sS" : "x-")); > - lsrwx(sb->st_mode , (sb->st_mode & S_ISTXT? "tT" : "x-")); > - > - printf (" %u,%u\t%lu\t%s\n", sb->st_uid, sb->st_gid, > - (u_long)sb->st_size, name); > -} > -#undef lsrwx > - > -int doboot = 1; > - > -static int > -Xnop(void) > -{ > - if (doboot) { > - doboot = 0; > - return (Xboot()); > - } > - > - return 0; > -} > - > -static int > -Xboot(void) > -{ > - if (cmd.argc > 1 && cmd.argv[1][0] != '-') { > - qualify((cmd.argv[1]? cmd.argv[1]: cmd.image)); > - if (bootparse(2)) > - return 0; > - } else { > - if (bootparse(1)) > - return 0; > - snprintf(cmd.path, sizeof cmd.path, "%s:%s", > - cmd.bootdev, cmd.image); > - } > - > - return 1; > -} > - > -/* > - * Qualifies the path adding necessary dev > - */ > - > -static char * > -qualify(char *name) > -{ > - char *p; > - > - for (p = name; *p; p++) > - if (*p == ':') > - break; > - if (*p == ':') > - strlcpy(cmd.path, name, sizeof(cmd.path)); > - else > - snprintf(cmd.path, sizeof cmd.path, "%s:%s", > - cmd.bootdev, name); > - return cmd.path; > -} > - > -static int > -Xreboot(void) > -{ > - printf("Rebooting...\n"); > - reboot(0); > - return 0; /* just in case */ > -} > - > -int > -upgrade(void) > -{ > - struct stat sb; > - const char *path; > - int ret = 0; > - > - path = disk_open(qualify("/bsd.upgrade")); > - if (path == NULL) > - return 0; > - if (stat(path, &sb) == 0 && S_ISREG(sb.st_mode)) > - ret = 1; > - disk_close(); > - > - return ret; > -} > diff --git a/sys/arch/octeon/stand/rdboot/cmd.h > b/sys/arch/octeon/stand/rdboot/cmd.h > deleted file mode 100644 > index 1ffafde59ef..00000000000 > --- a/sys/arch/octeon/stand/rdboot/cmd.h > +++ /dev/null > @@ -1,65 +0,0 @@ > -/* $OpenBSD: cmd.h,v 1.1 2019/07/17 14:36:32 visa Exp $ */ > - > -/* > - * Copyright (c) 1997 Michael Shalayeff > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or without > - * modification, are permitted provided that the following conditions > - * are met: > - * 1. Redistributions of source code must retain the above copyright > - * notice, this list of conditions and the following disclaimer. > - * 2. Redistributions in binary form must reproduce the above copyright > - * notice, this list of conditions and the following disclaimer in the > - * documentation and/or other materials provided with the distribution. > - * > - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE > - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > - * SUCH DAMAGE. > - * > - */ > - > -#define CMD_BUFF_SIZE 133 > -#define BOOTDEVLEN 1024 > - > -struct cmd_table { > - char *cmd_name; > - char cmd_type; > -#define CMDT_CMD 0 > -#define CMDT_VAR 1 > -#define CMDT_SET 2 > -#define CMDT_MDC 3 > - int (*cmd_exec)(void); > -}; > - > -struct cmd_state { > - char bootdev[BOOTDEVLEN]; /* device */ > - char image[MAXPATHLEN - 16]; /* image */ > - unsigned char bootduid[8]; /* duid of root disk */ > - int boothowto; /* howto */ > - int hasduid; > - char *conf; /* /etc/boot.conf normally */ > - int timeout; > - > - char path[MAXPATHLEN]; /* buffer for pathname compose */ > - const struct cmd_table *cmd; > - int argc; > - char *argv[8]; /* XXX i hope this is enough */ > -}; > -extern struct cmd_state cmd; > - > -int getcmd(void); > -int read_conf(void); > -int bootparse(int); > -void boot(dev_t); > - > -int upgrade(void); > -int docmd(void); /* No longer static: needed by regress test */ > diff --git a/sys/arch/octeon/stand/rdboot/disk.c > b/sys/arch/octeon/stand/rdboot/disk.c > deleted file mode 100644 > index eda089bc34f..00000000000 > --- a/sys/arch/octeon/stand/rdboot/disk.c > +++ /dev/null > @@ -1,208 +0,0 @@ > -/* $OpenBSD: disk.c,v 1.2 2020/05/26 13:30:47 visa Exp $ */ > - > -/* > - * Copyright (c) 2019 Visa Hankala > - * > - * Permission to use, copy, modify, and/or distribute this software for any > - * purpose with or without fee is hereby granted, provided that the above > - * copyright notice and this permission notice appear in all copies. > - * > - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > - */ > - > -#include <sys/types.h> > -#include <sys/param.h> > -#include <sys/disklabel.h> > -#include <sys/dkio.h> > -#include <sys/ioctl.h> > -#include <sys/mount.h> > -#include <sys/stat.h> > -#include <sys/sysctl.h> > - > -#include <err.h> > -#include <errno.h> > -#include <fcntl.h> > -#include <stdio.h> > -#include <stdlib.h> > -#include <string.h> > -#include <unistd.h> > -#include <util.h> > - > -#include "cmd.h" > - > -int disk_proberoot(const char *); > - > -int mounted = 0; > -int rdroot = -1; /* fd that points to the root of the ramdisk */ > - > -void > -disk_init(void) > -{ > - char rootdevs[1024]; > - char *devname, *disknames, *ptr; > - size_t size; > - int mib[2]; > - > - rdroot = open("/", O_RDONLY); > - if (rdroot == -1) > - err(1, "failed to open root directory fd"); > - > - if (strlen(cmd.bootdev) != 0) > - return; > - > - mib[0] = CTL_HW; > - mib[1] = HW_DISKNAMES; > - size = 0; > - if (sysctl(mib, 2, NULL, &size, NULL, 0) == -1) { > - fprintf(stderr, "%s: cannot get hw.disknames: %s\n", __func__, > - strerror(errno)); > - return; > - } > - disknames = malloc(size); > - if (disknames == NULL) { > - fprintf(stderr, "%s: out of memory\n", __func__); > - return; > - } > - if (sysctl(mib, 2, disknames, &size, NULL, 0) == -1) { > - fprintf(stderr, "%s: cannot get hw.disknames: %s\n", __func__, > - strerror(errno)); > - free(disknames); > - return; > - } > - > - printf("probing disks\n"); > - rootdevs[0] = '\0'; > - ptr = disknames; > - while ((devname = strsep(&ptr, ",")) != NULL) { > - char *duid; > - > - duid = strchr(devname, ':'); > - if (duid == NULL) > - continue; > - *duid++ = '\0'; > - > - /* Disk without a duid cannot be a root device. */ > - if (strlen(duid) == 0) > - continue; > - > - if (disk_proberoot(devname)) { > - if (strlen(cmd.bootdev) == 0) { > - snprintf(cmd.bootdev, sizeof(cmd.bootdev), > - "%sa", devname); > - } > - (void)strlcat(rootdevs, " ", sizeof(rootdevs)); > - (void)strlcat(rootdevs, devname, sizeof(rootdevs)); > - } > - } > - if (strlen(rootdevs) != 0) > - printf("available root devices:%s\n", rootdevs); > - else > - printf("no root devices found\n"); > -} > - > -int > -disk_proberoot(const char *devname) > -{ > - static const char *const names[] = { > - "bin", "dev", "etc", "home", "mnt", "root", "sbin", "tmp", > - "usr", "var", NULL > - }; > - struct ufs_args ffs_args; > - struct stat st; > - char path[32]; > - int i, is_root = 1; > - > - snprintf(path, sizeof(path), "/dev/%sa", devname); > - memset(&ffs_args, 0, sizeof(ffs_args)); > - ffs_args.fspec = path; > - if (mount(MOUNT_FFS, "/mnt", MNT_RDONLY, &ffs_args) == -1) > - return 0; > - for (i = 0; names[i] != NULL; i++) { > - snprintf(path, sizeof(path), "/mnt/%s", names[i]); > - if (stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) { > - is_root = 0; > - break; > - } > - } > - (void)unmount("/mnt", 0); > - > - return is_root; > -} > - > -const char * > -disk_open(const char *path) > -{ > - struct ufs_args ffs_args; > - struct disklabel label; > - char devname[32]; > - char *devpath; > - const char *ptr; > - int fd; > - > - if (mounted) { > - fprintf(stderr, "%s: cannot nest\n", __func__); > - return NULL; > - } > - > - ptr = strchr(path, ':'); > - if (ptr != NULL) { > - snprintf(devname, sizeof(devname), "%.*s", > - (int)(ptr - path), path); > - ptr++; /* skip ':' */ > - } else { > - strlcpy(devname, cmd.bootdev, sizeof(devname)); > - ptr = path; > - } > - if (strlen(devname) == 0) { > - fprintf(stderr, "no device specified\n"); > - return NULL; > - } > - > - cmd.hasduid = 0; > - fd = opendev(devname, O_RDONLY, OPENDEV_BLCK, &devpath); > - if (fd != -1) { > - if (ioctl(fd, DIOCGDINFO, &label) != -1) { > - memcpy(cmd.bootduid, label.d_uid, 8); > - cmd.hasduid = 1; > - } > - close(fd); > - } else { > - fprintf(stderr, "failed to open device %s: %s\n", devname, > - strerror(errno)); > - return NULL; > - } > - > - memset(&ffs_args, 0, sizeof(ffs_args)); > - ffs_args.fspec = devpath; > - if (mount(MOUNT_FFS, "/mnt", MNT_FORCE | MNT_NOATIME, > - &ffs_args) == -1) { > - fprintf(stderr, "failed to mount %s: %s\n", devpath, > - strerror(errno)); > - return NULL; > - } > - if (chroot("/mnt") == -1) { > - fprintf(stderr, "failed to chroot: %s\n", strerror(errno)); > - (void)unmount("/mnt", 0); > - return NULL; > - } > - mounted = 1; > - > - return ptr; > -} > - > -void > -disk_close(void) > -{ > - if (mounted) { > - (void)fchdir(rdroot); > - (void)chroot("."); > - mounted = 0; > - (void)unmount("/mnt", 0); > - } > -} > diff --git a/sys/arch/octeon/stand/rdboot/disk.h > b/sys/arch/octeon/stand/rdboot/disk.h > deleted file mode 100644 > index ac0d1879bb0..00000000000 > --- a/sys/arch/octeon/stand/rdboot/disk.h > +++ /dev/null > @@ -1,21 +0,0 @@ > -/* $OpenBSD: disk.h,v 1.1 2019/07/17 14:36:32 visa Exp $ */ > - > -/* > - * Copyright (c) 2019 Visa Hankala > - * > - * Permission to use, copy, modify, and/or distribute this software for any > - * purpose with or without fee is hereby granted, provided that the above > - * copyright notice and this permission notice appear in all copies. > - * > - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > - */ > - > -void disk_init(void); > -const char *disk_open(const char *); > -void disk_close(void); > diff --git a/sys/arch/octeon/stand/rdboot/rdboot.c > b/sys/arch/octeon/stand/rdboot/rdboot.c > index 850279c42a4..136d2c89003 100644 > --- a/sys/arch/octeon/stand/rdboot/rdboot.c > +++ b/sys/arch/octeon/stand/rdboot/rdboot.c > @@ -1,9 +1,9 @@ > /* $OpenBSD: rdboot.c,v 1.8 2020/12/09 18:10:19 krw Exp $ */ > > /* > - * Copyright (c) 2019-2020 Visa Hankala > + * Copyright (c) 2019-2022 Visa Hankala > * > - * Permission to use, copy, modify, and/or distribute this software for any > + * Permission to use, copy, modify, and distribute this software for any > * purpose with or without fee is hereby granted, provided that the above > * copyright notice and this permission notice appear in all copies. > * > @@ -19,10 +19,8 @@ > #include <sys/types.h> > #include <sys/param.h> > #include <sys/ioctl.h> > -#include <sys/mount.h> > #include <sys/reboot.h> > -#include <sys/select.h> > -#include <sys/stat.h> > +#include <sys/sysctl.h> > > #include <err.h> > #include <errno.h> > @@ -36,28 +34,25 @@ > #include <util.h> > > #include <machine/octboot.h> > -#include <machine/param.h> > > -#include "cmd.h" > -#include "disk.h" > +#define BOOTDEVLEN 1024 > > -#define DEVRANDOM "/dev/random" > -#define BOOTRANDOM "/etc/random.seed" > -#define BOOTRANDOM_MAX 256 /* no point being greater than RC4STATE > */ > -#define KERNEL "/bsd" > +void findroot(char *, size_t); > > -int loadrandom(void); > -void kexec(void); > +void saboot_boot(int); > +void saboot_cninit(void); > +int saboot_proberoot(const char *); > > -struct cmd_state cmd; > +char rootdev[32]; > int octbootfd = -1; > -const char version[] = "1.3"; > + > +extern unsigned char bootduid[]; > +extern int bootduidvalid; > > int > main(void) > { > - char rootdev[PATH_MAX]; > - int fd, hasboot; > + int fd; > > fd = open(_PATH_CONSOLE, O_RDWR); > login_tty(fd); > @@ -65,179 +60,140 @@ main(void) > /* Keep stdout unbuffered to mimic ordinary bootblocks. */ > setvbuf(stdout, NULL, _IONBF, 0); > > - printf(">> OpenBSD/" MACHINE " BOOT %s\n", version); > - > octbootfd = open("/dev/octboot", O_WRONLY); > if (octbootfd == -1) > err(1, "cannot open boot control device"); > > - memset(&cmd, 0, sizeof(cmd)); > - cmd.boothowto = 0; > - cmd.conf = "/etc/boot.conf"; > - strlcpy(cmd.image, KERNEL, sizeof(cmd.image)); > - cmd.timeout = 5; > + saboot_cninit(); > + saboot_boot(0); > > + reboot(RB_AUTOBOOT | RB_TIMEBAD); > + > + return 0; > +} > + > +void > +machdep(void) > +{ > if (ioctl(octbootfd, OBIOC_GETROOTDEV, rootdev) == -1) { > - if (errno != ENOENT) > + if (errno != ENOENT) { > fprintf(stderr, "cannot get rootdev from kernel: %s\n", > strerror(errno)); > + } > + findroot(rootdev, sizeof(rootdev)); > } else { > - snprintf(cmd.bootdev, sizeof(cmd.bootdev), "%s%sa", > - rootdev, isduid(rootdev, OPENDEV_PART) ? "." : ""); > + if (isduid(rootdev, OPENDEV_PART)) > + (void)strlcat(rootdev, ".", sizeof(rootdev)); > + (void)strlcat(rootdev, "a", sizeof(rootdev)); > } > +} > > - disk_init(); > - > - if (upgrade()) { > - strlcpy(cmd.image, "/bsd.upgrade", sizeof(cmd.image)); > - printf("upgrade detected: switching to %s\n", cmd.image); > +void > +findroot(char *rootdev, size_t rootdevlen) > +{ > + char rootdevs[1024]; > + char devname[32]; > + char *diskname, *disknames, *ptr; > + size_t size; > + int mib[2]; > + > + mib[0] = CTL_HW; > + mib[1] = HW_DISKNAMES; > + size = 0; > + if (sysctl(mib, 2, NULL, &size, NULL, 0) == -1) { > + fprintf(stderr, "%s: cannot get hw.disknames: %s\n", __func__, > + strerror(errno)); > + return; > + } > + disknames = malloc(size); > + if (disknames == NULL) { > + fprintf(stderr, "%s: out of memory\n", __func__); > + return; > + } > + if (sysctl(mib, 2, disknames, &size, NULL, 0) == -1) { > + fprintf(stderr, "%s: cannot get hw.disknames: %s\n", __func__, > + strerror(errno)); > + free(disknames); > + return; > } > > - hasboot = read_conf(); > - > - for (;;) { > - if (hasboot <= 0) { > - do { > - printf("boot> "); > - } while (!getcmd()); > + printf("probing disks\n"); > + rootdevs[0] = '\0'; > + ptr = disknames; > + while ((diskname = strsep(&ptr, ",")) != NULL) { > + char *duid; > + > + duid = strchr(diskname, ':'); > + if (duid == NULL) > + continue; > + *duid++ = '\0'; > + > + /* Disk without a duid cannot contain a root device. */ > + if (strlen(duid) == 0) > + continue; > + > + snprintf(devname, sizeof(devname), "%sa", diskname); > + if (saboot_proberoot(devname)) { > + if (strlen(rootdev) == 0) > + (void)strlcpy(rootdev, devname, rootdevlen); > + (void)strlcat(rootdevs, " ", sizeof(rootdevs)); > + (void)strlcat(rootdevs, devname, sizeof(rootdevs)); > } > - > - if (loadrandom() == 0) > - cmd.boothowto |= RB_GOODRANDOM; > - > - kexec(); > - > - hasboot = 0; > - strlcpy(cmd.image, KERNEL, sizeof(cmd.image)); > - printf("will try %s\n", cmd.image); > + } > + if (strlen(rootdevs) != 0) { > + printf("available root devices:%s\n", rootdevs); > + } else { > + printf("no root devices found\n"); > + (void)strlcpy(rootdev, "sd0a", sizeof(rootdev)); > } > > - return 0; > + free(disknames); > } > > -int > -loadrandom(void) > +void > +devboot(dev_t dev, char *bootdev) > { > - char buf[BOOTRANDOM_MAX]; > - struct stat sb; > - int fd, ret = 0; > - > - /* Read the file from the device specified by the kernel path. */ > - if (disk_open(cmd.path) == NULL) > - return -1; > - fd = open(BOOTRANDOM, O_RDONLY); > - if (fd == -1) { > - fprintf(stderr, "%s: cannot open %s: %s", __func__, BOOTRANDOM, > - strerror(errno)); > - disk_close(); > - return -1; > - } > - if (fstat(fd, &sb) == 0) { > - if (sb.st_mode & S_ISTXT) { > - printf("NOTE: random seed is being reused.\n"); > - ret = -1; > - } > - if (read(fd, buf, sizeof(buf)) != sizeof(buf)) > - ret = -1; > - fchmod(fd, sb.st_mode | S_ISTXT); > - } else { > - ret = -1; > - } > - close(fd); > - disk_close(); > - > - /* > - * Push the whole buffer to the entropy pool. > - * The kernel will use the entropy on kexec(). > - * It does not matter if some of the buffer content is uninitialized. > - */ > - fd = open(DEVRANDOM, O_WRONLY); > - if (fd == -1) { > - fprintf(stderr, "%s: cannot open %s: %s", __func__, > - DEVRANDOM, strerror(errno)); > - return -1; > - } > - write(fd, buf, sizeof(buf)); > - close(fd); > - return ret; > + strlcpy(bootdev, rootdev, BOOTDEVLEN); > } > > void > -kexec(void) > +_rtt(void) > +{ > + reboot(RB_AUTOBOOT | RB_TIMEBAD); > +} > + > +void > +hexdump(const void *addr, size_t size) > +{ > + /* Not worth it. There are better ways to study the system. */ > + printf("not implemented\n"); > +} > + > +int > +ukexec(void *kimg, size_t klen, int howto) > { > struct octboot_kexec_args kargs; > - struct stat sb; > char boothowtostr[32]; > char rootdev[32]; > - char *kimg = NULL; > - const char *path; > - ssize_t n; > - off_t pos; > - int argc, fd = -1, ret; > - > - path = disk_open(cmd.path); > - if (path == NULL) > - return; > - > - fd = open(path, O_RDONLY); > - if (fd == -1) > - goto load_failed; > - if (fstat(fd, &sb) == -1) > - goto load_failed; > - if (!S_ISREG(sb.st_mode) || sb.st_size == 0) { > - errno = ENOEXEC; > - goto load_failed; > - } > - > - kimg = malloc(sb.st_size); > - if (kimg == NULL) > - goto load_failed; > - > - pos = 0; > - while (pos < sb.st_size) { > - n = read(fd, kimg + pos, sb.st_size - pos); > - if (n == -1) > - goto load_failed; > - pos += n; > - } > - > - close(fd); > - disk_close(); > + int argc = 0; > > memset(&kargs, 0, sizeof(kargs)); > kargs.kimg = kimg; > - kargs.klen = sb.st_size; > - argc = 0; > - if (cmd.boothowto != 0) { > + kargs.klen = klen; > + if (howto != 0) { > snprintf(boothowtostr, sizeof(boothowtostr), "boothowto=%d", > - cmd.boothowto); > + howto); > kargs.argv[argc++] = boothowtostr; > } > - if (cmd.hasduid) { > + if (bootduidvalid) { > snprintf(rootdev, sizeof(rootdev), > "rootdev=%02x%02x%02x%02x%02x%02x%02x%02x", > - cmd.bootduid[0], cmd.bootduid[1], > - cmd.bootduid[2], cmd.bootduid[3], > - cmd.bootduid[4], cmd.bootduid[5], > - cmd.bootduid[6], cmd.bootduid[7]); > + bootduid[0], bootduid[1], > + bootduid[2], bootduid[3], > + bootduid[4], bootduid[5], > + bootduid[6], bootduid[7]); > kargs.argv[argc++] = rootdev; > } > > - printf("booting %s\n", cmd.path); > - ret = ioctl(octbootfd, OBIOC_KEXEC, &kargs); > - if (ret == -1) > - fprintf(stderr, "failed to execute kernel %s: %s\n", > - cmd.path, strerror(errno)); > - else > - fprintf(stderr, "kexec() returned unexpectedly\n"); > - free(kimg); > - return; > - > -load_failed: > - fprintf(stderr, "failed to load kernel %s: %s\n", > - cmd.path, strerror(errno)); > - if (fd != -1) > - close(fd); > - disk_close(); > - free(kimg); > + return ioctl(octbootfd, OBIOC_KEXEC, &kargs); > } > diff --git a/sys/arch/octeon/stand/rdboot/unixcall.c > b/sys/arch/octeon/stand/rdboot/unixcall.c > new file mode 100644 > index 00000000000..b4aa25c4cea > --- /dev/null > +++ b/sys/arch/octeon/stand/rdboot/unixcall.c > @@ -0,0 +1,153 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2022 Visa Hankala > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/types.h> > +#include <sys/disklabel.h> > +#include <sys/dkio.h> > +#include <sys/ioctl.h> > +#include <errno.h> > +#include <fcntl.h> > +#include <poll.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <termios.h> > +#include <time.h> > +#include <unistd.h> > +#include <util.h> > + > +#include "unixcall.h" > + > +unsigned char bootduid[8]; > +int bootduidvalid; > + > +time_t > +getsecs(void) > +{ > + return time(NULL); > +} > + > +void > +ucninit(void) > +{ > + struct termios tio; > + > + tcgetattr(STDIN_FILENO, &tio); > + cfmakeraw(&tio); > + tio.c_iflag = ICRNL|IXANY; > + tio.c_oflag = OPOST|ONLCR; > + tio.c_cflag = CREAD|CS8|HUPCL; > + tio.c_cc[VMIN] = 1; > + tio.c_cc[VTIME] = 0; > + tcsetattr(STDIN_FILENO, TCSANOW, &tio); > +} > + > +int > +ucngetc(int dopoll) > +{ > + struct pollfd pfd[1]; > + int ret; > + char b; > + > + pfd[0].fd = STDIN_FILENO; > + pfd[0].events = POLLIN; > + > + for (;;) { > + ret = poll(pfd, 1, dopoll ? 0 : -1); > + if (dopoll) > + return ret > 0; > + if (ret > 0) { > + if (read(STDIN_FILENO, &b, 1) < 1) > + return -1; > + return b; > + } > + } > +} > + > +void > +ucnputc(int c) > +{ > + char b = c; > + > + write(STDOUT_FILENO, &b, 1); > +} > + > +int > +udiskopen(const char *devname, int *pfd) > +{ > + struct disklabel label; > + > + if (*devname == '\0' || *devname == '/') > + return ENODEV; > + *pfd = opendev(devname, O_RDWR, 0, NULL); > + if (*pfd == -1) > + return errno; > + > + memset(bootduid, 0, sizeof(bootduid)); > + bootduidvalid = 0; > + if (ioctl(*pfd, DIOCGDINFO, &label) != -1) { > + memcpy(bootduid, label.d_uid, sizeof(bootduid)); > + bootduidvalid = 1; > + } > + > + return 0; > +} > + > +void > +udiskclose(int fd) > +{ > + close(fd); > +} > + > +int > +udiskread(int fd, void *buf, size_t nbytes, off_t offset, size_t *rbytes) > +{ > + ssize_t n; > + > + n = pread(fd, buf, nbytes, offset); > + if (n < 0) > + return errno; > + if (rbytes != NULL) > + *rbytes = n; > + return 0; > +} > + > +int > +udiskwrite(int fd, const void *buf, size_t nbytes, off_t offset, size_t > *wbytes) > +{ > + ssize_t n; > + > + n = pwrite(fd, buf, nbytes, offset); > + if (n < 0) > + return errno; > + if (wbytes != NULL) > + *wbytes = n; > + return 0; > +} > + > +void * > +umalloc(size_t size) > +{ > + return malloc(size); > +} > + > +void > +ufree(void *ptr) > +{ > + free(ptr); > +} > diff --git a/sys/arch/octeon/stand/rdboot/vars.c > b/sys/arch/octeon/stand/rdboot/vars.c > deleted file mode 100644 > index 926c8a6cb16..00000000000 > --- a/sys/arch/octeon/stand/rdboot/vars.c > +++ /dev/null > @@ -1,203 +0,0 @@ > -/* $OpenBSD: vars.c,v 1.1 2019/07/17 14:36:32 visa Exp $ */ > - > -/* > - * Copyright (c) 1998-2000 Michael Shalayeff > - * All rights reserved. > - * > - * Redistribution and use in source and binary forms, with or without > - * modification, are permitted provided that the following conditions > - * are met: > - * 1. Redistributions of source code must retain the above copyright > - * notice, this list of conditions and the following disclaimer. > - * 2. Redistributions in binary form must reproduce the above copyright > - * notice, this list of conditions and the following disclaimer in the > - * documentation and/or other materials provided with the distribution. > - * > - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR > - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE > - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL > - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS > - * OR SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS > INTERRUPTION) > - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY > - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > - * SUCH DAMAGE. > - * > - */ > - > -#include <sys/param.h> > -#include <sys/reboot.h> > - > -#include <limits.h> > -#include <stdio.h> > -#include <string.h> > -#include <stdlib.h> > - > -#include "cmd.h" > - > -extern int debug; > -int db_console = -1; > - > -static int Xdevice(void); > -#ifdef DEBUG > -static int Xdebug(void); > -#endif > -static int Xdb_console(void); > -static int Ximage(void); > -static int Xhowto(void); > -static int Xtimeout(void); > -int Xset(void); > - > -const struct cmd_table cmd_set[] = { > - {"howto", CMDT_VAR, Xhowto}, > -#ifdef DEBUG > - {"debug", CMDT_VAR, Xdebug}, > -#endif > - {"device", CMDT_VAR, Xdevice}, > - {"image", CMDT_VAR, Ximage}, > - {"timeout",CMDT_VAR, Xtimeout}, > - {"db_console", CMDT_VAR, Xdb_console}, > - {NULL,0} > -}; > - > -#ifdef DEBUG > -static int > -Xdebug(void) > -{ > - if (cmd.argc != 2) > - printf( "o%s\n", debug? "n": "ff" ); > - else > - debug = (cmd.argv[1][0] == '0' || > - (cmd.argv[1][0] == 'o' && cmd.argv[1][1] == 'f'))? > - 0: 1; > - return 0; > -} > -#endif > - > -int > -Xdb_console(void) > -{ > - if (cmd.argc != 2) { > - switch (db_console) { > - case 0: > - printf("off\n"); > - break; > - case 1: > - printf("on\n"); > - break; > - default: > - printf("unset\n"); > - break; > - } > - } else { > - if (strcmp(cmd.argv[1], "0") == 0 || > - strcmp(cmd.argv[1], "off") == 0) > - db_console = 0; > - else if (strcmp(cmd.argv[1], "1") == 0 || > - strcmp(cmd.argv[1], "on") == 0) > - db_console = 1; > - } > - > - return (0); > -} > - > -static int > -Xtimeout(void) > -{ > - if (cmd.argc != 2) > - printf( "%d\n", cmd.timeout ); > - else > - cmd.timeout = (int)strtol( cmd.argv[1], (char **)NULL, 0 ); > - return 0; > -} > - > -/* called only w/ no arguments */ > -int > -Xset(void) > -{ > - const struct cmd_table *ct; > - > - printf("boot\n"); > - for (ct = cmd_set; ct->cmd_name != NULL; ct++) { > - printf("%s\t ", ct->cmd_name); > - (*ct->cmd_exec)(); > - } > - return 0; > -} > - > -static int > -Xdevice(void) > -{ > - if (cmd.argc != 2) > - printf("%s\n", cmd.bootdev); > - else > - strlcpy(cmd.bootdev, cmd.argv[1], sizeof(cmd.bootdev)); > - return 0; > -} > - > -static int > -Ximage(void) > -{ > - if (cmd.argc != 2) > - printf("%s\n", cmd.image); > - else > - strlcpy(cmd.image, cmd.argv[1], sizeof(cmd.image)); > - return 0; > -} > - > -static int > -Xhowto(void) > -{ > - if (cmd.argc == 1) { > - if (cmd.boothowto) { > - putchar('-'); > - if (cmd.boothowto & RB_ASKNAME) > - putchar('a'); > - if (cmd.boothowto & RB_CONFIG) > - putchar('c'); > - if (cmd.boothowto & RB_SINGLE) > - putchar('s'); > - if (cmd.boothowto & RB_KDB) > - putchar('d'); > - } > - putchar('\n'); > - } else > - bootparse(1); > - return 0; > -} > - > -int > -bootparse(int i) > -{ > - char *cp; > - int howto = cmd.boothowto; > - > - for (; i < cmd.argc; i++) { > - cp = cmd.argv[i]; > - if (*cp == '-') { > - while (*++cp) { > - switch (*cp) { > - case 'a': > - howto |= RB_ASKNAME; > - break; > - case 'c': > - howto |= RB_CONFIG; > - break; > - case 's': > - howto |= RB_SINGLE; > - break; > - case 'd': > - howto |= RB_KDB; > - break; > - default: > - printf("howto: bad option: %c\n", *cp); > - return 1; > - } > - } > - } > - } > - cmd.boothowto = howto; > - return 0; > -} > diff --git a/sys/arch/octeon/stand/saboot/Makefile > b/sys/arch/octeon/stand/saboot/Makefile > new file mode 100644 > index 00000000000..73a328c8027 > --- /dev/null > +++ b/sys/arch/octeon/stand/saboot/Makefile > @@ -0,0 +1,64 @@ > +# $OpenBSD$ > + > +NOMAN= > + > +.if ${MACHINE} == "octeon" > +PROG= saboot.elf > + > +NM?= nm > +OBJCOPY?= objcopy > + > +S= ${.CURDIR}/../../../.. > + > +CFLAGS+= -Wall -ffreestanding -D_STANDALONE -nostdinc -fno-builtin > +CFLAGS+= -I${.CURDIR} > +CFLAGS+= -I${.OBJDIR} > +CFLAGS+= -I${S} > +CFLAGS+= -I${S}/lib/libsa > + > +LDFLAGS= -nostdlib > + > +SRCS= conf.c devopen.c loadfile.c saboot.c > + > +.PATH: ${S}/stand/boot > +SRCS+= boot.c cmd.c vars.c > + > +.PATH: ${S}/lib/libsa > +SRCS+= cons.c ctime.c exit.c getchar.c getfile.c getln.c > globals.c \ > + memcmp.c memcpy.c memmove.c memset.c printf.c putchar.c \ > + snprintf.c strchr.c strcmp.c strerror.c strlen.c strncmp.c \ > + strncpy.c strtol.c strtoll.c > +SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c \ > + fchmod.c fstat.c ioctl.c lseek.c open.c read.c readdir.c \ > + stat.c write.c > +SRCS+= arc4.c > +SRCS+= ufs.c ufs2.c > + > +REMAP_OBJ= ${PROG}.tmp > +CLEANFILES+= ${REMAP_OBJ} > + > +REMAP_LIST= ${PROG}.map > +CLEANFILES+= ${REMAP_LIST} > + > +# Build a relocatable object. > +# Add a prefix to the names of defined symbols so as to avoid name collisions > +# when linking with libc in the next step. > +${PROG}: ${OBJS} > + ${CC} ${LDFLAGS} -r -o ${REMAP_OBJ} ${OBJS} > + ${NM} -g ${REMAP_OBJ} | awk '$$1 != "U" && $$2 != "F" {printf("%s > saboot_%s\n", $$3, $$3)}' > ${REMAP_LIST} > + ${OBJCOPY} --redefine-syms=${REMAP_LIST} ${REMAP_OBJ} ${PROG} > + > +install: > + > +.if !make(clean) && !make(cleandir) && !make(includes) && !make(obj) > +.BEGIN: > + @([ -h machine ] || ln -s ${.CURDIR}/../../include machine) > + @([ -h mips64 ] || ln -s ${.CURDIR}/../../../mips64/include mips64) > +CLEANFILES+= machine mips64 > +.endif > + > +.else > +NOPROG= > +.endif > + > +.include <bsd.prog.mk> > diff --git a/sys/arch/octeon/stand/saboot/conf.c > b/sys/arch/octeon/stand/saboot/conf.c > new file mode 100644 > index 00000000000..a4e21f775ad > --- /dev/null > +++ b/sys/arch/octeon/stand/saboot/conf.c > @@ -0,0 +1,41 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2022 Visa Hankala > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <dev/cons.h> > + > +#include "libsa.h" > +#include <lib/libsa/ufs.h> > +#include <lib/libsa/ufs2.h> > + > +const char version[] = "2.0"; > + > +struct fs_ops file_system[] = { > + /* ufs filesystem */ > + { ufs_open, ufs_close, ufs_read, ufs_write, > + ufs_seek, ufs_stat, ufs_readdir, ufs_fchmod }, > + { ufs2_open, ufs2_close, ufs2_read, ufs2_write, > + ufs2_seek, ufs2_stat, ufs2_readdir, ufs2_fchmod }, > +}; > +int nfsys = nitems(file_system); > + > +struct consdev constab[] = { > + { unix_cnprobe, unix_cninit, unix_cngetc, unix_cnputc }, > + { NULL } > +}; > +struct consdev *cn_tab = constab; > diff --git a/sys/arch/octeon/stand/saboot/devopen.c > b/sys/arch/octeon/stand/saboot/devopen.c > new file mode 100644 > index 00000000000..ce378fe335c > --- /dev/null > +++ b/sys/arch/octeon/stand/saboot/devopen.c > @@ -0,0 +1,89 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2022 Visa Hankala > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > + > +#include "libsa.h" > +#include "unixcall.h" > + > +int diskstrategy(void *, int, daddr_t, size_t, void *, size_t *); > +int diskclose(struct open_file *); > + > +static struct devsw disk = { > + .dv_name = "disk", > + .dv_strategy = diskstrategy, > + .dv_close = diskclose, > +}; > + > +int > +diskstrategy(void *devdata, int rw, daddr_t bn, size_t reqcnt, > + void *buf, size_t *cnt) > +{ > + off_t offs; > + int error, fd; > + > + fd = (int)(intptr_t)devdata; > + offs = bn * DEV_BSIZE; > + switch (rw) { > + case F_READ: > + error = udiskread(fd, buf, reqcnt, offs, cnt); > + break; > + case F_WRITE: > + error = udiskwrite(fd, buf, reqcnt, offs, cnt); > + break; > + default: > + error = EINVAL; > + break; > + } > + return error; > +} > + > +int > +diskclose(struct open_file *f) > +{ > + int fd = (int)(intptr_t)f->f_devdata; > + > + udiskclose(fd); > + return 0; > +} > + > +#define MAXDEVNAME 24 > + > +int > +devopen(struct open_file *f, const char *fname, char **file) > +{ > + char devname[MAXDEVNAME]; > + const char *ptr; > + int error, fd; > + > + ptr = strchr(fname, ':'); > + if (ptr == NULL) > + return ENODEV; > + if (ptr - fname >= sizeof(devname)) > + return EINVAL; > + memcpy(devname, fname, ptr - fname); > + devname[ptr - fname] = '\0'; > + > + error = udiskopen(devname, &fd); > + if (error != 0) > + return error; > + *file = (char *)(ptr + 1); > + f->f_dev = &disk; > + f->f_devdata = (void *)(intptr_t)fd; > + return 0; > +} > diff --git a/sys/arch/octeon/stand/saboot/libsa.h > b/sys/arch/octeon/stand/saboot/libsa.h > new file mode 100644 > index 00000000000..40fd48cb79e > --- /dev/null > +++ b/sys/arch/octeon/stand/saboot/libsa.h > @@ -0,0 +1,30 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2022 Visa Hankala > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <lib/libsa/stand.h> > + > +#define DEFAULT_KERNEL_ADDRESS 0 > + > +void devboot(dev_t, char *); > +void machdep(void); > +void run_loadfile(uint64_t *, int); > + > +void unix_cnprobe(struct consdev *); > +void unix_cninit(struct consdev *); > +int unix_cngetc(dev_t); > +void unix_cnputc(dev_t, int); > diff --git a/sys/arch/octeon/stand/saboot/loadfile.c > b/sys/arch/octeon/stand/saboot/loadfile.c > new file mode 100644 > index 00000000000..1d03e5330e4 > --- /dev/null > +++ b/sys/arch/octeon/stand/saboot/loadfile.c > @@ -0,0 +1,115 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2022 Visa Hankala > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <sys/exec_elf.h> > + > +#include <lib/libsa/stand.h> > + > +#include "unixcall.h" > + > +static void *kernbuf; > +static size_t kernsize; > + > +int > +loadfile(const char *fname, uint64_t *marks, int flags) > +{ > + struct stat sb; > + char *buf = NULL; > + size_t pos, size = 0; > + ssize_t nread; > + int fd; > + > + free(kernbuf, kernsize); > + kernbuf = NULL; > + kernsize = 0; > + > + fd = open(fname, O_RDONLY); > + if (fd < 0) { > + printf("cannot open %s: %s\n", fname, strerror(errno)); > + return -1; > + } > + if (fstat(fd, &sb) < 0) { > + printf("fstat(): %s\n", strerror(errno)); > + goto fail; > + } > + size = sb.st_size; > + if (size < sizeof(Elf_Ehdr)) { > + printf("not ELF file\n"); > + goto fail; > + } > + > + buf = alloc(size); > + if (buf == NULL) { > + printf("cannot allocate %zu bytes: %s\n", size, > + strerror(errno)); > + goto fail; > + } > + > + pos = 0; > + while (pos < size) { > + nread = read(fd, buf + pos, size - pos); > + if (nread < 0) { > + printf("read(): %s\n", fname, strerror(errno)); > + goto fail; > + } > + if (nread == 0) { > + printf("short read\n"); > + goto fail; > + } > + pos += nread; > + } > + > + /* > + * Screen non-ELF files. > + * More proper validation is done at kexec time. > + */ > + if (buf[0] != ELFMAG0 || buf[1] != ELFMAG1 || > + buf[2] != ELFMAG2 || buf[3] != ELFMAG3) { > + printf("not ELF file\n"); > + goto fail; > + } > + > + printf("loading done\n"); > + > + kernbuf = buf; > + kernsize = size; > + return fd; > +fail: > + free(buf, size); > + close(fd); > + return -1; > +} > + > +void > +run_loadfile(uint64_t *marks, int howto) > +{ > + if (kernbuf == NULL) { > + printf("no kernel loaded\n"); > + return; > + } > + > + if (ukexec(kernbuf, kernsize, howto) == -1) > + printf("kexec(): %s\n", strerror(errno)); > + else > + printf("kexec() returned unexpectedly\n"); > + > + free(kernbuf, kernsize); > + kernbuf = NULL; > + kernsize = 0; > +} > diff --git a/sys/arch/octeon/stand/saboot/saboot.c > b/sys/arch/octeon/stand/saboot/saboot.c > new file mode 100644 > index 00000000000..5da6e8a9146 > --- /dev/null > +++ b/sys/arch/octeon/stand/saboot/saboot.c > @@ -0,0 +1,101 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2022 Visa Hankala > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <dev/cons.h> > + > +#include "libsa.h" > +#include "unixcall.h" > + > +int > +cnspeed(dev_t dev, int sp) > +{ > + return 115200; > +} > + > +char * > +ttyname(int fd) > +{ > + return "com0"; > +} > + > +dev_t > +ttydev(char *name) > +{ > + if (strcmp(name, "com0") != 0) > + return NODEV; > + return makedev(0, 0); > +} > + > +void > +unix_cnprobe(struct consdev *cn) > +{ > + cn->cn_pri = CN_HIGHPRI; > +} > + > +void > +unix_cninit(struct consdev *cn) > +{ > + ucninit(); > +} > + > +int > +unix_cngetc(dev_t dev) > +{ > + int dopoll = ((dev & 0x80) != 0); > + > + return ucngetc(dopoll); > +} > + > +void > +unix_cnputc(dev_t dev, int c) > +{ > + ucnputc(c); > +} > + > +void * > +alloc(unsigned int size) > +{ > + return umalloc(size); > +} > + > +void > +free(void *ptr, unsigned int size) > +{ > + ufree(ptr); > +} > + > +int > +proberoot(const char *devname) > +{ > + static const char *const names[] = { > + "bin", "dev", "etc", "home", "mnt", "root", "sbin", "tmp", > + "usr", "var", NULL > + }; > + struct stat st; > + char path[32]; > + int i; > + > + for (i = 0; names[i] != NULL; i++) { > + snprintf(path, sizeof(path), "%s:%s", devname, names[i]); > + if (stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) > + return 0; > + } > + > + return 1; > +} > diff --git a/sys/arch/octeon/stand/saboot/unixcall.h > b/sys/arch/octeon/stand/saboot/unixcall.h > new file mode 100644 > index 00000000000..83ba14d2430 > --- /dev/null > +++ b/sys/arch/octeon/stand/saboot/unixcall.h > @@ -0,0 +1,31 @@ > +/* $OpenBSD$ */ > + > +/* > + * Copyright (c) 2022 Visa Hankala > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +void ucninit(void); > +int ucngetc(int); > +void ucnputc(int); > + > +int udiskopen(const char *, int *); > +void udiskclose(int); > +int udiskread(int, void *, size_t, off_t, size_t *); > +int udiskwrite(int, const void *, size_t, off_t, size_t *); > + > +void ufree(void *); > +void *umalloc(size_t); > + > +int ukexec(void *, size_t, int); >