|
@@ -1,486 +0,0 @@
|
|
|
-/*------------------------------------------------------
|
|
|
- * Oberon Boot File Loader RC, JS 27.4.93/2.12.93, HP-UX 9.0 Version
|
|
|
- *
|
|
|
- * Oberon Boot File Loader for Linux
|
|
|
- * derived from HP and Windows Boot Loader
|
|
|
- * MAD, 23.05.94
|
|
|
- * PR, 01.02.95 support for sockets added
|
|
|
- * PR, 05.02.95 support for V24 added
|
|
|
- * PR, 23.12.95 migration to shared ELF libraries
|
|
|
- * g.f. 01.11.99 added InstallTrap
|
|
|
- * added Threads support
|
|
|
- * removed cmd line parameter evaluation
|
|
|
- * g.f. 22.11.04 call to mprotect added
|
|
|
- * g.f. 03.04.07 Darwin/Intel version
|
|
|
- *
|
|
|
- *-----------------------------------------------------------*/
|
|
|
-
|
|
|
-#ifdef DARWIN
|
|
|
-# undef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
|
|
|
-# define __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ 1059
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef LINUX
|
|
|
-# define _use_valloc /* use the obsolete valloc function instead of posix_memalign */
|
|
|
-#endif
|
|
|
-
|
|
|
-#include <sys/types.h>
|
|
|
-#include <fcntl.h>
|
|
|
-#include <dlfcn.h>
|
|
|
-#include <unistd.h>
|
|
|
-#include <stdlib.h>
|
|
|
-#include <stdio.h>
|
|
|
-#include <string.h>
|
|
|
-#include <errno.h>
|
|
|
-#include <sys/stat.h>
|
|
|
-#include <setjmp.h>
|
|
|
-#ifdef DARWIN
|
|
|
-# include <sys/ucontext.h>
|
|
|
-# include <sys/_types.h>
|
|
|
-# include <sys/signal.h>
|
|
|
-#endif
|
|
|
-#include <signal.h>
|
|
|
-#include <limits.h>
|
|
|
-#include "Threads.h"
|
|
|
-#include <sys/mman.h>
|
|
|
-#include <X11/Xlib.h>
|
|
|
-
|
|
|
-#define true 1
|
|
|
-#define false 0
|
|
|
-
|
|
|
-typedef void (*OberonProc)();
|
|
|
-
|
|
|
-typedef void* address;
|
|
|
-typedef unsigned int ADDR32;
|
|
|
-
|
|
|
-FILE *fd;
|
|
|
-char *AOSPATH;
|
|
|
-char path[4096];
|
|
|
-char *dirs[255];
|
|
|
-char fullname[512];
|
|
|
-int nofdir;
|
|
|
-char defaultpath[] = ".:/usr/aos/obj:/usr/aos/system:/usr/aos/fonts/Oberon";
|
|
|
-#ifdef SOLARIS
|
|
|
- char bootname[64] = "SolarisAosCore";
|
|
|
-#endif
|
|
|
-#ifdef LINUX
|
|
|
- char bootname[64] = "LinuxAosCore";
|
|
|
-#endif
|
|
|
-#ifdef DARWIN
|
|
|
- char bootname[64] = "DarwinAosCore";
|
|
|
-#endif
|
|
|
-
|
|
|
-size_t heapSize = 0x200000;
|
|
|
-size_t codeSize;
|
|
|
-address heapAdr, maxHeapAdr;
|
|
|
-int addrshift;
|
|
|
-unsigned int startOffset;
|
|
|
-int Argc;
|
|
|
-char **Argv;
|
|
|
-int debug;
|
|
|
-
|
|
|
-static stack_t sigstk;
|
|
|
-
|
|
|
-#define BLSIZE 4096
|
|
|
-#define SIGSTACKSIZE 64*BLSIZE
|
|
|
-
|
|
|
-typedef void(*trap_t)(long, void*, void*, int);
|
|
|
-
|
|
|
-static trap_t AosTrap;
|
|
|
-
|
|
|
-
|
|
|
-static void sighandler( int sig, siginfo_t *scp, void *ucp ) {
|
|
|
-
|
|
|
- if (debug | (AosTrap == NULL)) {
|
|
|
- printf("\nhandler for signal %d got called, ucp = %p\n", sig, ucp);
|
|
|
- if (AosTrap == NULL) exit(1);
|
|
|
- }
|
|
|
- AosTrap(0, ucp, scp, sig); /* rev. order: Oberon <--> C */
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void installHandler(int sig) {
|
|
|
- struct sigaction act;
|
|
|
- sigset_t mask;
|
|
|
- sigemptyset(&mask);
|
|
|
- act.sa_mask = mask;
|
|
|
- if (sig == SIGSEGV)
|
|
|
- act.sa_flags = SA_SIGINFO|SA_ONSTACK|SA_NODEFER;
|
|
|
- else
|
|
|
- act.sa_flags = SA_SIGINFO|SA_NODEFER;
|
|
|
- act.sa_sigaction = sighandler;
|
|
|
- if (sigaction( sig, &act, NULL ) != 0) {
|
|
|
- perror("sigaction");
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void InitSignalHandler() {
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 1; i <= 15; i++) {
|
|
|
- if (i != 9) installHandler( i );
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void InstallTrap(trap_t p) {
|
|
|
-
|
|
|
- if (debug)
|
|
|
- printf("Installing Aos Trap\n");
|
|
|
- AosTrap = p;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void SetSigaltstack() {
|
|
|
-
|
|
|
- if (sigaltstack(&sigstk, NULL) < 0)
|
|
|
- perror("sigaltstack");
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void CreateSignalstack() {
|
|
|
- sigstk.ss_sp = mmap( NULL, SIGSTACKSIZE,
|
|
|
- PROT_READ | PROT_WRITE,
|
|
|
- MAP_PRIVATE | MAP_ANON,
|
|
|
- -1, 0);
|
|
|
- if (sigstk.ss_sp == MAP_FAILED){
|
|
|
- printf("mmap for signalstack failed\n" );
|
|
|
- exit( 1 );
|
|
|
- }
|
|
|
- sigstk.ss_size = SIGSTACKSIZE;
|
|
|
- sigstk.ss_flags = 0;
|
|
|
- if (debug)
|
|
|
- printf( "Signalstack created [%p ... %p]\n",
|
|
|
- sigstk.ss_sp, sigstk.ss_sp + SIGSTACKSIZE );
|
|
|
- SetSigaltstack();
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-void* o_dlopen(char *lib, int mode) {
|
|
|
- void* handle;
|
|
|
-
|
|
|
- if (debug&1) printf("o_dlopen: %s\n", lib);
|
|
|
- if ((handle = dlopen(lib, mode)) == NULL) {
|
|
|
- if (debug&1)
|
|
|
- printf("o_dlopen: %s not loaded, error = %s\n", lib, dlerror());
|
|
|
- }
|
|
|
- if (debug&1) printf("o_dlopen: handle = %p\n", handle);
|
|
|
-
|
|
|
- return handle;
|
|
|
-}
|
|
|
-
|
|
|
-void o_dlclose(void* handle) /* not necessary */
|
|
|
-{
|
|
|
- dlclose(handle);
|
|
|
-}
|
|
|
-
|
|
|
-static int o_errno() {
|
|
|
-
|
|
|
- return errno;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-int o_stat(char* name, void* buf) {
|
|
|
- return stat(name, (struct stat *) buf);
|
|
|
-}
|
|
|
-
|
|
|
-int o_lstat(char* name, void* buf) {
|
|
|
- return lstat(name, (struct stat *) buf);
|
|
|
-}
|
|
|
-
|
|
|
-int o_fstat(int fd, void* buf) {
|
|
|
- return fstat(fd, (struct stat *) buf);
|
|
|
-}
|
|
|
-
|
|
|
-int o_open(char* name, int flags, int mode) {
|
|
|
- return open(name, flags, mode);
|
|
|
-}
|
|
|
-
|
|
|
-void *o_malloc( long size ) {
|
|
|
- return malloc( size );
|
|
|
-}
|
|
|
-
|
|
|
-int o_posix_memalign(void** buf, long alignment, long size ) {
|
|
|
-#ifdef _use_valloc
|
|
|
- *buf = valloc( size );
|
|
|
- if (*buf != NULL) return 0; else return -1;
|
|
|
-#else
|
|
|
- return posix_memalign( buf, alignment, size );
|
|
|
-#endif
|
|
|
-}
|
|
|
-
|
|
|
-int o_mprotect( void* addr, long len, int prot ) {
|
|
|
- return mprotect( addr, len, prot );
|
|
|
-}
|
|
|
-
|
|
|
-int o_lseek( int fd, long pos, int whence ) {
|
|
|
- return lseek( fd, pos, whence );
|
|
|
-}
|
|
|
-
|
|
|
-int o_cout( char c ) {
|
|
|
- printf( "%c", c );
|
|
|
-}
|
|
|
-
|
|
|
-address o_paramtest(int p1, int p2, int p3, int p4, int p5, int p6, int p7, address p8){
|
|
|
- printf("parameter test, p7=%d, p8=%p\n", p7, p8);
|
|
|
- return (address)-8;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static void (*oberonXErrorHandler) (long p4, long p3, long err, long displ );
|
|
|
-static void (*oberonXIOErrorHandler) (long p4, long p3, long p2, long displ );
|
|
|
-
|
|
|
-static int X11ErrorHandler( Display *d, XErrorEvent *err ) {
|
|
|
- printf( "X11ErrorHandler called\n" );
|
|
|
- oberonXErrorHandler( 0, 0, (long)err, (long)d );
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int X11IOErrorHandler( Display *d ) {
|
|
|
- printf( "X11IOErrorHandler called\n" );
|
|
|
- oberonXIOErrorHandler( 0, 0, 0, (long)d );
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void SetupXErrHandlers( void* XE, void* XIOE ) {
|
|
|
-
|
|
|
- if (debug)
|
|
|
- printf( "Setup X11 ErrorHandlers\n" );
|
|
|
- oberonXErrorHandler = XE;
|
|
|
- oberonXIOErrorHandler = XIOE;
|
|
|
-
|
|
|
- XSetErrorHandler(X11ErrorHandler);
|
|
|
- XSetIOErrorHandler(X11IOErrorHandler);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void o_dlsym(void* handle, char* symbol, void** adr)
|
|
|
-{
|
|
|
- if (strcmp("dlopen", symbol) == 0) *adr = o_dlopen;
|
|
|
- else if (strcmp("dlclose", symbol) == 0) *adr = o_dlclose;
|
|
|
- else if (strcmp("debug", symbol) == 0) *(int*)adr = debug;
|
|
|
- else if (strcmp("heapAdr", symbol) == 0) *adr = heapAdr;
|
|
|
- else if (strcmp("heapSize", symbol) == 0) *(size_t*)adr = heapSize;
|
|
|
- else if (strcmp("argc", symbol) == 0) *adr = &Argc;
|
|
|
- else if (strcmp("argv", symbol) == 0) *adr = Argv;
|
|
|
- else if (strcmp("errno", symbol) == 0) *adr = o_errno;
|
|
|
- else if (strcmp("cout", symbol) == 0) *adr = o_cout;
|
|
|
- else if (strcmp("paramtest", symbol) == 0) *adr = o_paramtest;
|
|
|
-
|
|
|
- else if (strcmp("open", symbol) == 0) *adr = o_open;
|
|
|
- else if (strcmp("stat", symbol) == 0) *adr = o_stat;
|
|
|
- else if (strcmp("lstat", symbol) == 0) *adr = o_lstat;
|
|
|
- else if (strcmp("fstat", symbol) == 0) *adr = o_fstat;
|
|
|
- else if (strcmp("lseek", symbol) == 0) *adr = o_lseek;
|
|
|
-
|
|
|
- else if (strcmp("malloc", symbol) == 0) *adr = o_malloc;
|
|
|
- else if (strcmp("posix_memalign", symbol) == 0) *adr = o_posix_memalign;
|
|
|
- else if (strcmp("mprotect", symbol) == 0) *adr = o_mprotect;
|
|
|
-
|
|
|
- else if (strcmp("InstallTrap", symbol) == 0) *adr = InstallTrap;
|
|
|
- else if (strcmp("InitXErrH", symbol) == 0) *adr = SetupXErrHandlers;
|
|
|
-#ifdef LINUX
|
|
|
- else if (strcmp("sigsetjmp", symbol) == 0) *adr = __sigsetjmp;
|
|
|
- else if (strcmp("setjmp", symbol) == 0) *adr = __sigsetjmp;
|
|
|
-#endif
|
|
|
- else if (strcmp("mtxInit", symbol) == 0) *adr = o_mtxInit;
|
|
|
- else if (strcmp("mtxDestroy", symbol) == 0) *adr = o_mtxDestroy;
|
|
|
- else if (strcmp("mtxLock", symbol) == 0) *adr = o_mtxLock;
|
|
|
- else if (strcmp("mtxUnlock", symbol) == 0) *adr = o_mtxUnlock;
|
|
|
- else if (strcmp("conInit", symbol) == 0) *adr = o_conInit;
|
|
|
- else if (strcmp("conDestroy", symbol) == 0) *adr = o_conDestroy;
|
|
|
- else if (strcmp("conWait", symbol) == 0) *adr = o_conWait;
|
|
|
- else if (strcmp("conSignal", symbol) == 0) *adr = o_conSignal;
|
|
|
- else if (strcmp("thrStart", symbol) == 0) *adr = o_thrStart;
|
|
|
- else if (strcmp("thrThis", symbol) == 0) *adr = o_thrThis;
|
|
|
- else if (strcmp("thrSleep", symbol) == 0) *adr = o_thrSleep;
|
|
|
- else if (strcmp("thrYield", symbol) == 0) *adr = o_thrYield;
|
|
|
- else if (strcmp("thrExit", symbol) == 0) *adr = o_thrExit;
|
|
|
- else if (strcmp("thrSuspend", symbol) == 0) *adr = o_thrSuspend;
|
|
|
- else if (strcmp("thrResume", symbol) == 0) *adr = o_thrResume;
|
|
|
- else if (strcmp("thrGetPriority", symbol) == 0) *adr = o_thrGetprio;
|
|
|
- else if (strcmp("thrSetPriority", symbol) == 0) *adr = o_thrSetprio;
|
|
|
- else if (strcmp("thrKill", symbol) == 0) *adr = o_thrKill;
|
|
|
- else if (strcmp("thrInitialize", symbol) == 0) *adr = o_thrInitialize;
|
|
|
- else {
|
|
|
- *adr = dlsym(handle, symbol);
|
|
|
- if (*adr == 0) {
|
|
|
- printf("o_dlsym: symbol %s not found\n", symbol);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/*----- Files Reading primitives -----*/
|
|
|
-
|
|
|
-
|
|
|
-int Rint() {
|
|
|
- unsigned char b[4]; int i;
|
|
|
-
|
|
|
- /* read little endian integer */
|
|
|
- for (i=0; i<4; i++) b[i] = fgetc(fd);
|
|
|
- return *((int*)b);
|
|
|
-}
|
|
|
-
|
|
|
-address RAddress() {
|
|
|
- unsigned char b[8]; int i;
|
|
|
-
|
|
|
- /* read little endian address */
|
|
|
- for (i=0; i<8; i++) b[i] = fgetc(fd);
|
|
|
- return *((address*)b);
|
|
|
-}
|
|
|
-
|
|
|
-int RNum() {
|
|
|
- int n, shift;
|
|
|
- unsigned char x;
|
|
|
-
|
|
|
- shift = 0; n = 0; x = fgetc(fd);
|
|
|
- while (x >= 128) {
|
|
|
- n += (x & 0x7f) << shift;
|
|
|
- shift += 7;
|
|
|
- x = fgetc(fd);
|
|
|
- }
|
|
|
- return n + (((x & 0x3f) - ((x >> 6) << 6)) << shift);
|
|
|
-}
|
|
|
-
|
|
|
-int CheckAddr( int no, int ofs, address adr ){
|
|
|
- if (adr >= heapAdr+startOffset & adr < maxHeapAdr) return 1;
|
|
|
- else {
|
|
|
- printf("bad relocation offset: no=%d, ofs=%x, pos=%p [%p...%p]\n",
|
|
|
- no, ofs, adr, heapAdr+startOffset, maxHeapAdr);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void Assert( int no, int ofs, address adr ){
|
|
|
- if (adr < heapAdr+startOffset || adr > maxHeapAdr)
|
|
|
- printf("bad relocated pointer value: no=%d, ofs=%x, ptr=%p [%p...%p]\n",
|
|
|
- no, ofs, adr, heapAdr+startOffset, maxHeapAdr);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void Relocate() {
|
|
|
- int no, len, ofs; ADDR32 *adr; ADDR32 val;
|
|
|
-
|
|
|
- len = RNum(); no = 0;
|
|
|
- if (debug) printf("relocate %d pointers\n", len);
|
|
|
- while (len != 0) {
|
|
|
- ofs = RNum(); ++no;
|
|
|
- adr = heapAdr + ofs;
|
|
|
- if (CheckAddr(no, ofs, adr)) {
|
|
|
- val = *adr;
|
|
|
- val += addrshift;
|
|
|
- *adr = val;
|
|
|
- Assert(no, ofs, (address)val);
|
|
|
- }
|
|
|
- len--;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void Boot() {
|
|
|
- address adr, fileHeapAdr, dlsymAdr;
|
|
|
- size_t len, fileHeapSize;
|
|
|
- int arch, d, notfound;
|
|
|
- OberonProc body;
|
|
|
-
|
|
|
- if (sizeof(address)==8) strcat(bootname, ".amd64");
|
|
|
- d = 0; notfound = 1;
|
|
|
- while ((d < nofdir) && notfound) {
|
|
|
- strcat(strcat(strcpy(fullname, dirs[d++]), "/"), bootname);
|
|
|
- fd = fopen(fullname, "r");
|
|
|
- if (fd != NULL) notfound = 0;
|
|
|
- }
|
|
|
- if (notfound) {
|
|
|
- printf("Aos BootLoader: boot file %s not found\n", bootname);
|
|
|
- exit(-1);
|
|
|
- }
|
|
|
- arch = Rint();
|
|
|
- if (arch != 8*sizeof(address)) {
|
|
|
- printf("bootfile %s has wrong architecture, got %d, expected %d\n",
|
|
|
- bootname, arch, (int)(8*sizeof(address)) );
|
|
|
- exit(-1);
|
|
|
- }
|
|
|
- fileHeapAdr = RAddress();
|
|
|
- fileHeapSize = Rint();
|
|
|
- if (fileHeapSize > heapSize) {
|
|
|
- printf("Aos BootLoader: heap too small\n");
|
|
|
- exit(-1);
|
|
|
- }
|
|
|
- adr = heapAdr; len = heapSize;
|
|
|
- while (len > 0) {
|
|
|
- *((int*)adr) = 0;
|
|
|
- len -= 4; adr += 4;
|
|
|
- }
|
|
|
- addrshift = heapAdr - fileHeapAdr;
|
|
|
-
|
|
|
-
|
|
|
- startOffset = Rint();
|
|
|
- len = Rint(); /* used heap */
|
|
|
- adr = heapAdr + startOffset;
|
|
|
- while (len > 0) {
|
|
|
- *(int*)adr = Rint(); adr += 4; len -= 4;
|
|
|
- }
|
|
|
- maxHeapAdr = adr - 32;
|
|
|
- if (debug) printf("code loading done [%p .. %p]\n", heapAdr, adr);
|
|
|
- body = (OberonProc)heapAdr + Rint();
|
|
|
- dlsymAdr = heapAdr + Rint();
|
|
|
- if (debug) printf("dlsymAdr, entrypoint: %p, %p\n", dlsymAdr, body);
|
|
|
-
|
|
|
- Relocate();
|
|
|
- *(address*)dlsymAdr = o_dlsym;
|
|
|
-
|
|
|
- fclose(fd);
|
|
|
- if(mprotect((void*)heapAdr, heapSize, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
|
|
|
- perror("mprotect");
|
|
|
- if (debug) printf("jump to AOS entrypoint\n");
|
|
|
- (*body)();
|
|
|
-}
|
|
|
-
|
|
|
-void InitPath() {
|
|
|
- int pos;
|
|
|
- char ch;
|
|
|
-
|
|
|
- if ((AOSPATH = getenv("AOSPATH")) == NULL) AOSPATH = defaultpath;
|
|
|
- strcpy(path, AOSPATH);
|
|
|
- pos = 0; nofdir = 0;
|
|
|
- ch = path[pos++];
|
|
|
- while (ch != '\0') {
|
|
|
- while ((ch == ' ') || (ch == ':')) ch = path[pos++];
|
|
|
- dirs[nofdir] = &path[pos-1];
|
|
|
- while ((ch > ' ') && (ch != ':')) ch = path[pos++];
|
|
|
- path[pos-1] = '\0';
|
|
|
- nofdir ++;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-int main(int argc, char *argv[])
|
|
|
-{
|
|
|
- char* p;
|
|
|
- void *a, *h;
|
|
|
-
|
|
|
- Argc = argc; Argv = argv;
|
|
|
-
|
|
|
- debug = 0;
|
|
|
- p = getenv("AOSDEBUG");
|
|
|
- if (p != NULL) debug = atoi(p);
|
|
|
- if (debug) {
|
|
|
- printf( "UnixAos Boot Loader 06.01.2016\n" );
|
|
|
- printf( "debug = %d\n", debug );
|
|
|
- }
|
|
|
- if (posix_memalign(&heapAdr, 4096, heapSize) != 0) {
|
|
|
- printf("Aos BootLoader: cannot allocate initial heap space\n");
|
|
|
- exit(-1);
|
|
|
- }
|
|
|
-
|
|
|
- InitPath();
|
|
|
- CreateSignalstack();
|
|
|
- InitSignalHandler();
|
|
|
-
|
|
|
- Boot();
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|