summaryrefslogtreecommitdiff
path: root/sys/arch/zaurus
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2005-01-10 00:24:21 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2005-01-10 00:24:21 +0000
commitb6c39ce7790cf6c5cb8b6689bef53e0b0195ea48 (patch)
treecd4d3fe3e773671d17eb5402884c1e1619c49c9d /sys/arch/zaurus
parentcca008b7320973326aff5a21889abe7a2a5b2f50 (diff)
(for now) on the linux side, do:
zaurus# insmod -f stand/zbsdldr/obj.i386.zaurus/zbsdldr.o zaurus# mknod /dev/zboot c 99 0 zaurus# cp bsd.rd /dev/zboot
Diffstat (limited to 'sys/arch/zaurus')
-rw-r--r--sys/arch/zaurus/stand/zbsdmod/Makefile18
-rw-r--r--sys/arch/zaurus/stand/zbsdmod/compat_linux.h101
-rw-r--r--sys/arch/zaurus/stand/zbsdmod/zbsdmod.c211
3 files changed, 330 insertions, 0 deletions
diff --git a/sys/arch/zaurus/stand/zbsdmod/Makefile b/sys/arch/zaurus/stand/zbsdmod/Makefile
new file mode 100644
index 00000000000..f8a31d631ed
--- /dev/null
+++ b/sys/arch/zaurus/stand/zbsdmod/Makefile
@@ -0,0 +1,18 @@
+OBJS= zbsdmod.o
+SRCS= zbsdmod.c
+NOMAN=
+
+all: ${OBJS}
+
+clean:
+ rm -f zbsdmod.o
+
+.include <bsd.prog.mk>
+
+afterinstall:
+ ${INSTALL} ${INSTALL_COPY} -o root -g wheel -m 644 \
+ ${OBJS} ${BINDIR}
+
+CFLAGS= -fno-stack-protector -Wall
+CFLAGS+= -DMACHINE=\"${MACHINE}\" -DUTS_RELEASE=\"2.4.20\"
+CPPFLAGS= -I${.CURDIR}/../include
diff --git a/sys/arch/zaurus/stand/zbsdmod/compat_linux.h b/sys/arch/zaurus/stand/zbsdmod/compat_linux.h
new file mode 100644
index 00000000000..d497e3c5f17
--- /dev/null
+++ b/sys/arch/zaurus/stand/zbsdmod/compat_linux.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
+ *
+ * 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.
+ */
+
+#if 0
+
+/* Define these unconditionally to get the .modinfo section. */
+#undef __KERNEL__
+#undef MODULE
+#define __KERNEL__
+#define MODULE
+
+/* Standard headers for Linux LKMs */
+#include <linux/kernel.h>
+#include <linux/modsetver.h>
+#include <linux/module.h>
+
+/*
+ * Include Linux 2.4.x headers.
+ */
+#include <linux/elf.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <asm/mach/map.h>
+
+#else
+
+/*
+ * Declare the things that we need from the Linux headers.
+ */
+
+#define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)-1000L)
+
+struct file;
+struct inode;
+
+typedef long loff_t;
+typedef int ssize_t;
+typedef unsigned int size_t;
+
+struct file_operations {
+ struct module *owner;
+ void (*llseek) (void);
+ ssize_t (*read) (struct file *, char *, size_t, loff_t *);
+ ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
+ void (*readdir) (void);
+ void (*poll) (void);
+ void (*ioctl) (void);
+ void (*mmap) (void);
+ int (*open) (struct inode *, struct file *);
+ void (*flush) (void);
+ int (*release) (struct inode *, struct file *);
+ void (*fsync) (void);
+ void (*fasync) (void);
+ void (*lock) (void);
+ void (*readv) (void);
+ void (*writev) (void);
+ void (*sendpage) (void);
+ void (*get_unmapped_area)(void);
+#ifdef MAGIC_ROM_PTR
+ void (*romptr) (void);
+#endif /* MAGIC_ROM_PTR */
+};
+
+extern struct file * open_exec(const char *);
+extern void fput(struct file *);
+extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
+extern int memcmp(const void *, const void *, unsigned int);
+extern int register_chrdev(unsigned int, const char *, struct file_operations *);
+extern int unregister_chrdev(unsigned int, const char *);
+extern void printk(const char *, ...);
+extern void *memcpy(void *, const void *, size_t);
+
+/* BSD headers */
+#include <sys/exec_elf.h>
+#include <errno.h>
+
+/* Linux LKM support */
+static const char __module_kernel_version[] __attribute__((section(".modinfo"))) =
+"kernel_version=" UTS_RELEASE;
+#if 1 /* def MODVERSIONS */
+static const char __module_using_checksums[] __attribute__((section(".modinfo"))) =
+"using_checksums=1";
+#endif
+
+#endif
diff --git a/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c b/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c
new file mode 100644
index 00000000000..0b8483b6ca5
--- /dev/null
+++ b/sys/arch/zaurus/stand/zbsdmod/zbsdmod.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
+ *
+ * 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.
+ *
+ * Zaurus OpenBSD bootstrap loader.
+ */
+
+#include "compat_linux.h"
+
+#define ZBOOTDEV_MAJOR 99
+#define ZBOOTDEV_NAME "zboot"
+#define ZBOOTMOD_NAME "zbsdmod"
+
+/* Prototypes */
+void elf32bsdboot(void);
+int init_module(void);
+void cleanup_module(void);
+
+ssize_t zbsdmod_write(struct file *, const char *, size_t, loff_t *);
+int zbsdmod_open(struct inode *, struct file *);
+int zbsdmod_close(struct inode *, struct file *);
+
+static struct file_operations fops = {
+ 0, /* struct module *owner */
+ 0, /* lseek */
+ 0, /* read */
+ zbsdmod_write, /* write */
+ 0, /* readdir */
+ 0, /* poll */
+ 0, /* ioctl */
+ 0, /* mmap */
+ zbsdmod_open, /* open */
+ 0, /* flush */
+ zbsdmod_close, /* release */
+ 0, /* sync */
+ 0, /* async */
+ 0, /* check media change */
+ 0, /* revalidate */
+ 0, /* lock */
+};
+
+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 int *addr;
+
+/* The maximum size of a kernel image is restricted to 8MB. */
+static int bsdimage[2097152]; /* XXX use kmalloc() */
+
+/*
+ * Boot the loaded BSD kernel image, or return if an error is found.
+ * Part of this routine is borrowed from sys/lib/libsa/loadfile.c.
+ */
+void
+elf32bsdboot(void)
+{
+ int cpsr;
+
+#define elf ((Elf32_Ehdr *)bsdimage)
+
+ 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));
+
+ for (i = 0; i < elf->e_phnum; i++) {
+
+ if (phdr[i].p_type != PT_LOAD ||
+ (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
+ continue;
+
+#define IS_TEXT(p) (p.p_flags & PF_X)
+#define IS_DATA(p) ((p.p_flags & PF_X) == 0)
+#define IS_BSS(p) (p.p_filesz < p.p_memsz)
+ /*
+ * XXX: Assume first address is lowest
+ */
+ if (IS_TEXT(phdr[i]) || IS_DATA(phdr[i])) {
+ sz = phdr[i].p_filesz;
+ while (sz > 0) {
+ sz--;
+ ((char *)phdr[i].p_vaddr)[sz] =
+ (((char *)elf) + phdr[i].p_offset)[sz];
+ }
+ }
+ }
+
+ addr = (int *)0xa0200000;
+ __asm__ volatile (
+ "mov r0, %0;"
+ "mov r2, #0;"
+ "mov r1, #(0x00000010 | 0x00000020);"
+ "mcr 15, 0, r1, c1, c0, 0;"
+ "mcr 15, 0, r2, c8, c7, 0 /* nail I+D TLB on ARMv4 and greater */;"
+ "mov pc, r0" :: "r"(addr) : "r0","r1","r2");
+}
+
+/*
+ * Initialize the LKM.
+ */
+int
+init_module()
+{
+ int rc;
+
+ rc = register_chrdev(ZBOOTDEV_MAJOR, ZBOOTDEV_NAME, &fops);
+ if (rc != 0) {
+ printk("%s: register_chrdev(%d, ...): error %d\n",
+ ZBOOTMOD_NAME, -rc);
+ return 1;
+ }
+
+ printk("%s: OpenBSD/" MACHINE " bootstrap device is %d,0\n",
+ ZBOOTMOD_NAME, ZBOOTDEV_MAJOR);
+
+ return 0;
+}
+
+/*
+ * Cleanup - undo whatever init_module did.
+ */
+void
+cleanup_module()
+{
+
+ (void)unregister_chrdev(ZBOOTDEV_MAJOR, ZBOOTDEV_NAME);
+
+ printk("%s: OpenBSD/" MACHINE " bootstrap device unloaded\n",
+ ZBOOTMOD_NAME);
+}
+
+
+ssize_t
+zbsdmod_write(struct file *f, const char *buf, size_t len, loff_t *offp)
+{
+
+ if (len < 1)
+ return 0;
+
+ if (*offp + len >= sizeof(bsdimage))
+ return EFBIG;
+
+ memcpy(((char *)bsdimage) + *offp, buf, len);
+
+ *offp += len;
+ if (*offp > position)
+ position = *offp;
+
+ return len;
+}
+
+int
+zbsdmod_open(struct inode *ino, struct file *f)
+{
+
+ /* XXX superuser check */
+
+ if (isopen)
+ return -EBUSY;
+
+ isopen = 1;
+ position = 0;
+
+ return 0;
+}
+
+int
+zbsdmod_close(struct inode *ino, struct file *f)
+{
+
+ if (isopen) {
+ if (position > 0) {
+ printk("%s: loaded %d bytes\n", ZBOOTDEV_NAME,
+ position);
+#ifndef _TEST
+ elf32bsdboot();
+ printk("%s: boot failed\n", ZBOOTDEV_NAME);
+#else
+ printk("/* boot() */\n");
+#endif
+ }
+ isopen = 0;
+ return 0;
+ }
+
+ return -EBUSY;
+}