summaryrefslogtreecommitdiff
path: root/sys/arch/zaurus
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2005-01-24 22:20:34 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2005-01-24 22:20:34 +0000
commitd9a0dc0f4bcf7d5ac6f5316f003783365d410075 (patch)
treea7dd0cba27396504d195411c153329ec1daef51a /sys/arch/zaurus
parent32356993b1ac13df40ffc6361a209ad088fb166f (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.h12
-rw-r--r--sys/arch/zaurus/stand/zboot/loadfile.c64
-rw-r--r--sys/arch/zaurus/stand/zboot/unixdev.c31
-rw-r--r--sys/arch/zaurus/stand/zboot/unixsys.S4
-rw-r--r--sys/arch/zaurus/stand/zbsdmod/zbsdmod.c43
-rw-r--r--sys/arch/zaurus/zaurus/zaurus_machdep.c26
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