diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-01-10 00:24:21 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2005-01-10 00:24:21 +0000 |
commit | b6c39ce7790cf6c5cb8b6689bef53e0b0195ea48 (patch) | |
tree | cd4d3fe3e773671d17eb5402884c1e1619c49c9d /sys/arch/zaurus | |
parent | cca008b7320973326aff5a21889abe7a2a5b2f50 (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/Makefile | 18 | ||||
-rw-r--r-- | sys/arch/zaurus/stand/zbsdmod/compat_linux.h | 101 | ||||
-rw-r--r-- | sys/arch/zaurus/stand/zbsdmod/zbsdmod.c | 211 |
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; +} |