aos.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. /*------------------------------------------------------
  2. * Oberon Boot File Loader RC, JS 27.4.93/2.12.93, HP-UX 9.0 Version
  3. *
  4. * Oberon Boot File Loader for Linux
  5. * derived from HP and Windows Boot Loader
  6. * MAD, 23.05.94
  7. * PR, 01.02.95 support for sockets added
  8. * PR, 05.02.95 support for V24 added
  9. * PR, 23.12.95 migration to shared ELF libraries
  10. * g.f. 01.11.99 added InstallTrap
  11. * added Threads support
  12. * removed cmd line parameter evaluation
  13. * g.f. 22.11.04 call to mprotect added
  14. * g.f. 03.04.07 Darwin/Intel version
  15. *
  16. *-----------------------------------------------------------*/
  17. #ifdef DARWIN
  18. # undef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
  19. # define __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ 1059
  20. #endif
  21. #ifdef LINUX
  22. # define _use_valloc /* use the obsolete valloc function instead of posix_memalign */
  23. #endif
  24. #include <sys/types.h>
  25. #include <fcntl.h>
  26. #include <dlfcn.h>
  27. #include <unistd.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <errno.h>
  32. #include <sys/stat.h>
  33. #include <setjmp.h>
  34. #ifdef DARWIN
  35. # include <sys/ucontext.h>
  36. # include <sys/_types.h>
  37. # include <sys/signal.h>
  38. #endif
  39. #include <signal.h>
  40. #include <limits.h>
  41. #include "Threads.h"
  42. #include <sys/mman.h>
  43. #include <X11/Xlib.h>
  44. typedef void (*OberonProc)();
  45. typedef void* address;
  46. FILE *fd;
  47. char *AOSPATH;
  48. char path[4096];
  49. char *dirs[255];
  50. char fullname[512];
  51. int nofdir;
  52. char defaultpath[] = ".:/usr/aos/obj:/usr/aos/system:/usr/aos/fonts";
  53. #ifdef SOLARIS
  54. char bootname[64] = "SolarisAosCore";
  55. #endif
  56. #ifdef LINUX
  57. char bootname[64] = "LinuxAosCore";
  58. #endif
  59. #ifdef DARWIN
  60. char bootname[64] = "DarwinAosCore";
  61. #endif
  62. size_t heapSize;
  63. size_t codeSize;
  64. address heapAdr;
  65. int Argc;
  66. char **Argv;
  67. int debug;
  68. static stack_t sigstk;
  69. #define BLSIZE 4096
  70. #define SIGSTACKSIZE 32*BLSIZE
  71. typedef void(*trap_t)(long, void*, void*, int);
  72. static trap_t AosTrap;
  73. static void sighandler( int sig, siginfo_t *scp, void *ucp ) {
  74. if (debug | (AosTrap == NULL)) {
  75. printf("\nhandler for signal %d got called, ucp = %p\n", sig, ucp);
  76. if (AosTrap == NULL) exit(1);
  77. }
  78. AosTrap(0, ucp, scp, sig); /* rev. order: Oberon <--> C */
  79. }
  80. static void installHandler(int sig) {
  81. struct sigaction act;
  82. sigset_t mask;
  83. sigemptyset(&mask);
  84. act.sa_mask = mask;
  85. act.sa_flags = SA_SIGINFO|SA_ONSTACK|SA_NODEFER;
  86. act.sa_sigaction = sighandler;
  87. if (sigaction( sig, &act, NULL ) != 0) {
  88. perror("sigaction");
  89. }
  90. }
  91. void InitSignalHandler() {
  92. int i;
  93. for (i = 1; i <= 15; i++) {
  94. if (i != 9) installHandler( i );
  95. }
  96. }
  97. static void InstallTrap(trap_t p) {
  98. if (debug)
  99. printf("Installing Aos Trap\n");
  100. AosTrap = p;
  101. }
  102. void SetSigaltstack() {
  103. if (sigaltstack(&sigstk, NULL) < 0)
  104. perror("sigaltstack");
  105. }
  106. static void CreateSignalstack() {
  107. sigstk.ss_sp = mmap( NULL, SIGSTACKSIZE,
  108. PROT_READ | PROT_WRITE,
  109. MAP_PRIVATE | MAP_ANON,
  110. -1, 0);
  111. if (sigstk.ss_sp == MAP_FAILED){
  112. printf("mmap for signalstack failed\n" );
  113. exit( 1 );
  114. }
  115. sigstk.ss_size = SIGSTACKSIZE;
  116. sigstk.ss_flags = 0;
  117. if (debug)
  118. printf( "Signalstack created [%p ... %p]\n",
  119. sigstk.ss_sp, sigstk.ss_sp + SIGSTACKSIZE );
  120. SetSigaltstack();
  121. }
  122. void* o_dlopen(char *lib, int mode) {
  123. void* handle;
  124. if (debug&1) printf("o_dlopen: %s\n", lib);
  125. if ((handle = dlopen(lib, mode)) == NULL) {
  126. if (debug&1)
  127. printf("o_dlopen: %s not loaded, error = %s\n", lib, dlerror());
  128. }
  129. if (debug&1) printf("o_dlopen: handle = %p\n", handle);
  130. return handle;
  131. }
  132. void o_dlclose(void* handle) /* not necessary */
  133. {
  134. dlclose(handle);
  135. }
  136. static int o_errno() {
  137. return errno;
  138. }
  139. int o_stat(char* name, void* buf) {
  140. return stat(name, (struct stat *) buf);
  141. }
  142. int o_lstat(char* name, void* buf) {
  143. return lstat(name, (struct stat *) buf);
  144. }
  145. int o_fstat(int fd, void* buf) {
  146. return fstat(fd, (struct stat *) buf);
  147. }
  148. int o_open(char* name, int flags, int mode) {
  149. return open(name, flags, mode);
  150. }
  151. void *o_malloc( long size ) {
  152. return malloc( size );
  153. }
  154. int o_posix_memalign(void** buf, long alignment, long size ) {
  155. #ifdef _use_valloc
  156. *buf = valloc( size );
  157. if (*buf != NULL) return 0; else return -1;
  158. #else
  159. return posix_memalign( buf, alignment, size );
  160. #endif
  161. }
  162. int o_mprotect( void* addr, long len, int prot ) {
  163. return mprotect( addr, len, prot );
  164. }
  165. int o_lseek( int fd, long pos, int whence ) {
  166. return lseek( fd, pos, whence );
  167. }
  168. int o_cout( char c ) {
  169. printf( "%c", c );
  170. }
  171. static void (*oberonXErrorHandler) (long p4, long p3, long err, long displ );
  172. static void (*oberonXIOErrorHandler) (long p4, long p3, long p2, long displ );
  173. static int X11ErrorHandler( Display *d, XErrorEvent *err ) {
  174. printf( "X11ErrorHandler called\n" );
  175. oberonXErrorHandler( 0, 0, (long)err, (long)d );
  176. }
  177. static int X11IOErrorHandler( Display *d ) {
  178. printf( "X11IOErrorHandler called\n" );
  179. oberonXIOErrorHandler( 0, 0, 0, (long)d );
  180. }
  181. void SetupXErrHandlers( void* XE, void* XIOE ) {
  182. if (debug)
  183. printf( "Setup X11 ErrorHandlers\n" );
  184. oberonXErrorHandler = XE;
  185. oberonXIOErrorHandler = XIOE;
  186. XSetErrorHandler(X11ErrorHandler);
  187. XSetIOErrorHandler(X11IOErrorHandler);
  188. }
  189. void o_dlsym(void* handle, char* symbol, void** adr)
  190. {
  191. if (debug==(-1)) printf("o_dlsym: %p %s\n", handle, symbol);
  192. if (strcmp("dlopen", symbol) == 0) *adr = o_dlopen;
  193. else if (strcmp("dlclose", symbol) == 0) *adr = o_dlclose;
  194. else if (strcmp("debug", symbol) == 0) *(int*)adr = debug;
  195. else if (strcmp("heapAdr", symbol) == 0) *adr = heapAdr;
  196. else if (strcmp("heapSize", symbol) == 0) *(size_t*)adr = heapSize;
  197. else if (strcmp("argc", symbol) == 0) *adr = &Argc;
  198. else if (strcmp("argv", symbol) == 0) *adr = Argv;
  199. else if (strcmp("errno", symbol) == 0) *adr = o_errno;
  200. else if (strcmp("cout", symbol) == 0) *adr = o_cout;
  201. else if (strcmp("open", symbol) == 0) *adr = o_open;
  202. else if (strcmp("stat", symbol) == 0) *adr = o_stat;
  203. else if (strcmp("lstat", symbol) == 0) *adr = o_lstat;
  204. else if (strcmp("fstat", symbol) == 0) *adr = o_fstat;
  205. else if (strcmp("lseek", symbol) == 0) *adr = o_lseek;
  206. else if (strcmp("malloc", symbol) == 0) *adr = o_malloc;
  207. else if (strcmp("posix_memalign", symbol) == 0) *adr = o_posix_memalign;
  208. else if (strcmp("mprotect", symbol) == 0) *adr = o_mprotect;
  209. else if (strcmp("InstallTrap", symbol) == 0) *adr = InstallTrap;
  210. else if (strcmp("InitXErrH", symbol) == 0) *adr = SetupXErrHandlers;
  211. #ifdef LINUX
  212. else if (strcmp("sigsetjmp", symbol) == 0) *adr = __sigsetjmp;
  213. else if (strcmp("setjmp", symbol) == 0) *adr = __sigsetjmp;
  214. #endif
  215. else if (strcmp("mtxInit", symbol) == 0) *adr = o_mtxInit;
  216. else if (strcmp("mtxDestroy", symbol) == 0) *adr = o_mtxDestroy;
  217. else if (strcmp("mtxLock", symbol) == 0) *adr = o_mtxLock;
  218. else if (strcmp("mtxUnlock", symbol) == 0) *adr = o_mtxUnlock;
  219. else if (strcmp("conInit", symbol) == 0) *adr = o_conInit;
  220. else if (strcmp("conDestroy", symbol) == 0) *adr = o_conDestroy;
  221. else if (strcmp("conWait", symbol) == 0) *adr = o_conWait;
  222. else if (strcmp("conSignal", symbol) == 0) *adr = o_conSignal;
  223. else if (strcmp("thrStart", symbol) == 0) *adr = o_thrStart;
  224. else if (strcmp("thrThis", symbol) == 0) *adr = o_thrThis;
  225. else if (strcmp("thrSleep", symbol) == 0) *adr = o_thrSleep;
  226. else if (strcmp("thrYield", symbol) == 0) *adr = o_thrYield;
  227. else if (strcmp("thrExit", symbol) == 0) *adr = o_thrExit;
  228. else if (strcmp("thrSuspend", symbol) == 0) *adr = o_thrSuspend;
  229. else if (strcmp("thrResume", symbol) == 0) *adr = o_thrResume;
  230. else if (strcmp("thrGetPriority", symbol) == 0) *adr = o_thrGetprio;
  231. else if (strcmp("thrSetPriority", symbol) == 0) *adr = o_thrSetprio;
  232. else if (strcmp("thrKill", symbol) == 0) *adr = o_thrKill;
  233. else if (strcmp("thrInitialize", symbol) == 0) *adr = o_thrInitialize;
  234. else {
  235. *adr = dlsym(handle, symbol);
  236. if (*adr == 0) {
  237. printf("o_dlsym: symbol %s not found\n", symbol);
  238. }
  239. }
  240. }
  241. /*----- Files Reading primitives -----*/
  242. int Rint() {
  243. unsigned char b[4]; int i;
  244. /* read little endian integer */
  245. for (i=0; i<4; i++) b[i] = fgetc(fd);
  246. return *((int*)b);
  247. }
  248. address RAddress() {
  249. unsigned char b[8]; int i;
  250. /* read little endian address */
  251. for (i=0; i<8; i++) b[i] = fgetc(fd);
  252. return *((address*)b);
  253. }
  254. int RNum() {
  255. int n, shift;
  256. unsigned char x;
  257. shift = 0; n = 0; x = fgetc(fd);
  258. while (x >= 128) {
  259. n += (x & 0x7f) << shift;
  260. shift += 7;
  261. x = fgetc(fd);
  262. }
  263. return n + (((x & 0x3f) - ((x >> 6) << 6)) << shift);
  264. }
  265. void Assert( address x ) {
  266. address y;
  267. if((x < heapAdr) | (x >= heapAdr + heapSize)) {
  268. printf("bad reloc. pos %p [%p, %p]\n", x, heapAdr, heapAdr+heapSize);
  269. }
  270. if (x > heapAdr+codeSize) {
  271. y = *(address*)x;
  272. if((y < heapAdr) | (y >= heapAdr+heapSize)) {
  273. printf("bad reloc. value %p [%p, %p]\n", y, heapAdr, heapAdr+heapSize);
  274. }
  275. }
  276. }
  277. void Relocate(size_t shift) {
  278. int len; address *adr;
  279. len = RNum();
  280. while (len != 0) {
  281. adr = heapAdr + RNum();
  282. *adr += shift;
  283. Assert( adr );
  284. len--;
  285. }
  286. }
  287. void Boot() {
  288. address adr, fileHeapAdr, dlsymAdr;
  289. size_t shift, len, fileHeapSize;
  290. int arch, d, notfound;
  291. OberonProc body;
  292. d = 0; notfound = 1;
  293. while ((d < nofdir) && notfound) {
  294. strcat(strcat(strcpy(fullname, dirs[d++]), "/"), bootname);
  295. fd = fopen(fullname, "r");
  296. if (fd != NULL) notfound = 0;
  297. }
  298. if (notfound) {
  299. printf("Aos BootLoader: boot file %s not found\n", bootname);
  300. exit(-1);
  301. }
  302. arch = Rint();
  303. if (arch != 8*sizeof(address)) {
  304. printf("bootfile %s has wrong architecture, got %d, expected %d\n", bootname, arch, (int)(8*sizeof(address)) );
  305. exit(-1);
  306. }
  307. fileHeapAdr = RAddress();
  308. fileHeapSize = Rint();
  309. if (fileHeapSize > heapSize) {
  310. printf("Aos BootLoader: heap too small\n");
  311. exit(-1);
  312. }
  313. adr = heapAdr; len = heapSize;
  314. while (len > 0) {
  315. *((int*)adr) = 0;
  316. len -= 4; adr += 4;
  317. }
  318. shift = heapAdr - fileHeapAdr;
  319. adr = heapAdr + Rint();
  320. len = Rint(); /* used heap */
  321. while (len > 0) {
  322. *(int*)adr = Rint(); adr += 4; len -= 4;
  323. }
  324. body = (OberonProc)heapAdr + Rint();
  325. dlsymAdr = heapAdr + Rint();
  326. Relocate(shift);
  327. *(address*)dlsymAdr = o_dlsym;
  328. fclose(fd);
  329. if(mprotect((void*)heapAdr, heapSize, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
  330. perror("mprotect");
  331. (*body)();
  332. }
  333. void InitPath() {
  334. int pos;
  335. char ch;
  336. if ((AOSPATH = getenv("AOSPATH")) == NULL) AOSPATH = defaultpath;
  337. strcpy(path, AOSPATH);
  338. pos = 0; nofdir = 0;
  339. ch = path[pos++];
  340. while (ch != '\0') {
  341. while ((ch == ' ') || (ch == ':')) ch = path[pos++];
  342. dirs[nofdir] = &path[pos-1];
  343. while ((ch > ' ') && (ch != ':')) ch = path[pos++];
  344. path[pos-1] = '\0';
  345. nofdir ++;
  346. }
  347. }
  348. int main(int argc, char *argv[])
  349. {
  350. char* p;
  351. void *a, *h;
  352. Argc = argc; Argv = argv;
  353. debug = 0;
  354. p = getenv("AOSDEBUG");
  355. if (p != NULL) debug = atoi(p);
  356. if (debug) {
  357. printf( "UnixAos Boot Loader 27.10.2013\n" );
  358. printf( "debug = %d\n", debug );
  359. }
  360. heapSize = 0x200000;
  361. #ifdef _use_valloc
  362. heapAdr = valloc( heapSize );
  363. if (heapAdr == 0) {
  364. #else
  365. if (posix_memalign(&heapAdr, 4096, heapSize) != 0) {
  366. #endif
  367. printf("Aos BootLoader: cannot allocate initial heap space\n");
  368. exit(-1);
  369. }
  370. InitPath();
  371. CreateSignalstack();
  372. InitSignalHandler();
  373. Boot();
  374. return 0;
  375. }