diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-01-24 22:20:34 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-01-24 22:20:34 +0000 |
commit | d9a0dc0f4bcf7d5ac6f5316f003783365d410075 (patch) | |
tree | a7dd0cba27396504d195411c153329ec1daef51a /sys/arch/zaurus | |
parent | 32356993b1ac13df40ffc6361a209ad088fb166f (diff) |
Pass boot arguments from zboot/zbsdmod to the loaded kernel, and cope
with 32-bit lseek() in zboot (make 'boot' and 'ls' work above 2G).
ok drahn@
Diffstat (limited to 'sys/arch/zaurus')
-rw-r--r-- | sys/arch/zaurus/stand/zboot/compat_linux.h | 12 | ||||
-rw-r--r-- | sys/arch/zaurus/stand/zboot/loadfile.c | 64 | ||||
-rw-r--r-- | sys/arch/zaurus/stand/zboot/unixdev.c | 31 | ||||
-rw-r--r-- | sys/arch/zaurus/stand/zboot/unixsys.S | 4 | ||||
-rw-r--r-- | sys/arch/zaurus/stand/zbsdmod/zbsdmod.c | 43 | ||||
-rw-r--r-- | sys/arch/zaurus/zaurus/zaurus_machdep.c | 26 |
6 files changed, 135 insertions, 45 deletions
diff --git a/sys/arch/zaurus/stand/zboot/compat_linux.h b/sys/arch/zaurus/stand/zboot/compat_linux.h index d785b91f71f..77e50bdcd3f 100644 --- a/sys/arch/zaurus/stand/zboot/compat_linux.h +++ b/sys/arch/zaurus/stand/zboot/compat_linux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat_linux.h,v 1.3 2005/01/10 21:50:54 deraadt Exp $ */ +/* $OpenBSD: compat_linux.h,v 1.4 2005/01/24 22:20:33 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -25,13 +25,21 @@ #include <compat/linux/linux_fcntl.h> #endif +#define INT_LIMIT(x) (~((x)1 << (sizeof(x)*8 - 1))) +#define OFFSET_MAX INT_LIMIT(long long) +#define OFFT_OFFSET_MAX INT_LIMIT(long) + #undef O_RDONLY #undef O_WRONLY #undef SEEK_SET +#undef SEEK_CUR #define O_RDONLY LINUX_O_RDONLY #define O_WRONLY LINUX_O_WRONLY #define SEEK_SET 0 +#define SEEK_CUR 1 + +#define EOVERFLOW 75 /* linux/asm/unistd.h */ #define __NR_SYSCALL_BASE 0x900000 @@ -40,7 +48,7 @@ #define __NR_write (__NR_SYSCALL_BASE+ 4) #define __NR_open (__NR_SYSCALL_BASE+ 5) #define __NR_close (__NR_SYSCALL_BASE+ 6) -#define __NR_lseek (__NR_SYSCALL_BASE+ 19) +#define __NR_lseek32 (__NR_SYSCALL_BASE+ 19) #define __NR_ioctl (__NR_SYSCALL_BASE+ 54) #define __NR__new_select (__NR_SYSCALL_BASE+142) #define __NR_select __NR__new_select /* XXX */ diff --git a/sys/arch/zaurus/stand/zboot/loadfile.c b/sys/arch/zaurus/stand/zboot/loadfile.c index a9e2bcbc9ff..a87e035b66d 100644 --- a/sys/arch/zaurus/stand/zboot/loadfile.c +++ b/sys/arch/zaurus/stand/zboot/loadfile.c @@ -1,5 +1,5 @@ /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */ -/* $OpenBSD: loadfile.c,v 1.1 2005/01/10 00:25:03 deraadt Exp $ */ +/* $OpenBSD: loadfile.c,v 1.2 2005/01/24 22:20:33 uwe Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -91,6 +91,7 @@ #include "compat_linux.h" #include "pathnames.h" #include <lib/libsa/loadfile.h> +#include <stand/boot/cmd.h> #define BOOT_ZBOOT @@ -630,9 +631,56 @@ static int zboot_exec(int fd, u_long *marks, int flags) { char buf[512]; + char *p; int tofd; int sz; - int total = 0; + int i; + + /* XXX cheating here by assuming that Xboot() was called before. */ + + tofd = uopen(_PATH_ZBOOT, O_WRONLY); + if (tofd == -1) { + printf("%s: can't open (errno %d)\n", _PATH_ZBOOT, errno); + return 1; + } + + p = cmd.path; + for (; *p != '\0'; p++) + if (*p == ':') { + strlcpy(buf, p+1, sizeof(buf)); + break; + } + if (*p == '\0') + strlcpy(buf, cmd.path, sizeof(buf)); + + p = buf; + for (; *p == '/'; p++) + ; + + sz = strlen(p); + if (uwrite(tofd, p, sz) != sz) { + printf("zboot_exec: argument write error\n"); + goto err; + } + + buf[0] = ' '; + i = (cmd.argc > 1 && cmd.argv[1][0] != '-') ? 2 : 1; + for (; i < cmd.argc; i++) { + + if (i > 0 && uwrite(tofd, buf, 1) != 1) { + printf("zboot_exec: argument write error\n"); + goto err; + } + + sz = strlen(cmd.argv[i]); + if (uwrite(tofd, cmd.argv[i], sz) != sz) { + printf("zboot_exec: argument write error\n"); + goto err; + } + } + + /* Commit boot arguments. */ + uclose(tofd); tofd = uopen(_PATH_ZBOOT, O_WRONLY); if (tofd == -1) { @@ -650,7 +698,6 @@ zboot_exec(int fd, u_long *marks, int flags) printf("%s: write error\n", _PATH_ZBOOT); goto err; } - total += sz; } if (sz < 0) { @@ -662,19 +709,12 @@ zboot_exec(int fd, u_long *marks, int flags) printf("zboot_exec: write error\n"); goto err; } - total += sz; - - /* - * Module is now armed. Reboot is triggered in run_loadfile(). - */ - - printf("zboot_exec: %d bytes written\n", total); - close(tofd); + uclose(tofd); return 0; err: - close(tofd); + uclose(tofd); return 1; } #endif /* BOOT_ZBOOT */ diff --git a/sys/arch/zaurus/stand/zboot/unixdev.c b/sys/arch/zaurus/stand/zboot/unixdev.c index 5460099a34f..400b6adc2dc 100644 --- a/sys/arch/zaurus/stand/zboot/unixdev.c +++ b/sys/arch/zaurus/stand/zboot/unixdev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: unixdev.c,v 1.2 2005/01/11 11:47:11 uwe Exp $ */ +/* $OpenBSD: unixdev.c,v 1.3 2005/01/24 22:20:33 uwe Exp $ */ /* * Copyright (c) 1996-1998 Michael Shalayeff @@ -43,12 +43,15 @@ unixstrategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf, size_t *rsize) { int rc = 0; + off_t off; #ifdef UNIX_DEBUG printf("unixstrategy: %s %d bytes @ %d\n", (rw==F_READ?"reading":"writing"), size, blk); #endif - if ((rc = ulseek((int)devdata, blk * DEV_BSIZE, 0)) >= 0) + + off = (off_t)blk * DEV_BSIZE; + if ((rc = ulseek((int)devdata, off, SEEK_SET)) >= 0) rc = (rw==F_READ) ? uread((int)devdata, buf, size) : uwrite((int)devdata, buf, size); @@ -112,13 +115,31 @@ unixioctl(struct open_file *f, u_long cmd, void *data) return uioctl((int)f->f_devdata, cmd, data); } -#if 0 off_t ulseek(int fd, off_t off, int wh) { - return __syscall((quad_t)SYS_lseek, fd, 0, off, wh); + extern long ulseek32(int, long, int); + off_t r; + + /* XXX only SEEK_SET is used, so anything else can fail for now. */ + + if (wh == SEEK_SET) { + if (ulseek32(fd, 0, SEEK_SET) != 0) + return -1; + while (off > OFFT_OFFSET_MAX) { + off -= OFFT_OFFSET_MAX; + if (ulseek32(fd, OFFT_OFFSET_MAX, SEEK_CUR) < 0 && + errno != EOVERFLOW) + return -1; + } + r = ulseek32(fd, (long)off, SEEK_CUR); + if (r == -1 && errno == EOVERFLOW) + r = off; + } else + r = ulseek32(fd, (long)off, wh); + + return r; } -#endif void diff --git a/sys/arch/zaurus/stand/zboot/unixsys.S b/sys/arch/zaurus/stand/zboot/unixsys.S index 3c12e7db0d4..22d5146dd9f 100644 --- a/sys/arch/zaurus/stand/zboot/unixsys.S +++ b/sys/arch/zaurus/stand/zboot/unixsys.S @@ -1,4 +1,4 @@ -/* $OpenBSD: unixsys.S,v 1.3 2005/01/10 21:50:54 deraadt Exp $ */ +/* $OpenBSD: unixsys.S,v 1.4 2005/01/24 22:20:33 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -30,7 +30,7 @@ RSYSCALL(open) RSYSCALL(read) RSYSCALL(write) -RSYSCALL(lseek) +RSYSCALL(lseek32) RSYSCALL(ioctl) RSYSCALL(close) RSYSCALL(exit) diff --git a/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c b/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c index 358c07fe90b..2094ab19c00 100644 --- a/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c +++ b/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zbsdmod.c,v 1.4 2005/01/14 08:10:17 uwe Exp $ */ +/* $OpenBSD: zbsdmod.c,v 1.5 2005/01/24 22:20:33 uwe Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de> @@ -20,6 +20,9 @@ #include "compat_linux.h" +#define BOOTARGS_BUFSIZ 256 +#define BOOTARGS_MAJIC 0x4f425344 + #define ZBOOTDEV_MAJOR 99 #define ZBOOTDEV_MODE 0222 #define ZBOOTDEV_NAME "zboot" @@ -57,13 +60,14 @@ static int isopen; static loff_t position; /* Outcast local variables to avoid stack usage in elf32bsdboot(). */ -static Elf32_Phdr phdr[32]; static unsigned int sz; static int i; +static vaddr_t minv; static int *addr; /* The maximum size of a kernel image is restricted to 8MB. */ static int bsdimage[2097152]; /* XXX use kmalloc() */ +static char bootargs[BOOTARGS_BUFSIZ]; /* * Boot the loaded BSD kernel image, or return if an error is found. @@ -74,22 +78,19 @@ elf32bsdboot(void) { int cpsr; -#define elf ((Elf32_Ehdr *)bsdimage) +#define elf ((Elf32_Ehdr *)bsdimage) +#define phdr ((Elf32_Phdr *)((char *)elf + elf->e_phoff)) if (memcmp(elf->e_ident, ELFMAG, SELFMAG) != 0 || elf->e_ident[EI_CLASS] != ELFCLASS32) return; - sz = elf->e_phnum * sizeof(Elf32_Phdr); - while (sz > 0) { - sz--; - ((char *)phdr)[sz] = (((char *)elf) + elf->e_phoff)[sz]; - } - __asm__ volatile ("mrs %0, cpsr_all" : "=r" (cpsr)); cpsr |= 0xc0; /* set FI */ __asm__ volatile ("msr cpsr_all, %0" :: "r" (cpsr)); + minv = (vaddr_t)~0; + for (i = 0; i < elf->e_phnum; i++) { if (phdr[i].p_type != PT_LOAD || @@ -108,11 +109,19 @@ elf32bsdboot(void) sz--; ((char *)phdr[i].p_vaddr)[sz] = (((char *)elf) + phdr[i].p_offset)[sz]; + if (minv > phdr[i].p_vaddr) + minv = phdr[i].p_vaddr; } } } - addr = (int *)0xa0200000; + sz = BOOTARGS_BUFSIZ; + while (sz > 0) { + sz--; + ((char *)minv - BOOTARGS_BUFSIZ)[sz] = bootargs[sz]; + } + + addr = (int *)(elf->e_entry); __asm__ volatile ( "mov r0, %0;" "mov r2, #0;" @@ -208,12 +217,20 @@ zbsdmod_close(struct inode *ino, struct file *f) if (position > 0) { printk("%s: loaded %d bytes\n", ZBOOTDEV_NAME, position); + + if (position < BOOTARGS_BUFSIZ) { + *(int *)bootargs = BOOTARGS_MAJIC; + bootargs[position + sizeof(int)] = '\0'; + memcpy(bootargs + sizeof(int), bsdimage, + position); + } else { #ifndef _TEST - elf32bsdboot(); - printk("%s: boot failed\n", ZBOOTDEV_NAME); + elf32bsdboot(); + printk("%s: boot failed\n", ZBOOTDEV_NAME); #else - printk("/* boot() */\n"); + printk("/* boot() */\n"); #endif + } } isopen = 0; return 0; diff --git a/sys/arch/zaurus/zaurus/zaurus_machdep.c b/sys/arch/zaurus/zaurus/zaurus_machdep.c index ea5f3e67c96..770db4b4aab 100644 --- a/sys/arch/zaurus/zaurus/zaurus_machdep.c +++ b/sys/arch/zaurus/zaurus/zaurus_machdep.c @@ -236,10 +236,10 @@ extern struct user *proc0paddr; void zaurus_reset(void); void zaurus_powerdown(void); -#if 0 +#define BOOT_STRING_MAGIC 0x4f425344 + +char bootargs[MAX_BOOT_STRING]; void process_kernel_args(char *); -void parse_mi_bootargs(char *args); -#endif void consinit(void); void early_clkman(u_int, int); @@ -748,15 +748,11 @@ initarm(void *arg) (tmp & ~(1<<4)) | (1<<0)); } -#if 0 /* * Examine the boot args string for options we need to know about * now. */ - process_kernel_args((char *)nwbootinfo.bt_args); -#else - boothowto = RB_AUTOBOOT; -#endif + process_kernel_args((char *)0xa0200000 - MAX_BOOT_STRING - 1); #ifdef RAMDISK_HOOKS boothowto |= RB_DFLTROOT; #endif /* RAMDISK_HOOKS */ @@ -1178,15 +1174,22 @@ initarm(void *arg) return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); } -#if 0 void process_kernel_args(char *args) { + if (*(int *)args != BOOT_STRING_MAGIC) { + boothowto = RB_AUTOBOOT; + return; + } + + *(int *)args = 0; + args += sizeof(int); + boothowto = 0; /* Make a local copy of the bootargs */ - strncpy(bootargs, args, MAX_BOOT_STRING); + strncpy(bootargs, args, MAX_BOOT_STRING - sizeof(int)); args = bootargs; boot_file = bootargs; @@ -1206,9 +1209,10 @@ process_kernel_args(char *args) printf("bootfile: %s\n", boot_file); printf("bootargs: %s\n", boot_args); +#if 1 parse_mi_bootargs(boot_args); -} #endif +} #ifdef KGDB #ifndef KGDB_DEVNAME |