|
|
1.1 ! root 1: #define __LIBRARY__ ! 2: #include <unistd.h> ! 3: #include <time.h> ! 4: ! 5: /* ! 6: * we need this inline - forking from kernel space will result ! 7: * in NO COPY ON WRITE (!!!), until an execve is executed. This ! 8: * is no problem, but for the stack. This is handled by not letting ! 9: * main() use the stack at all after fork(). Thus, no function ! 10: * calls - which means inline code for fork too, as otherwise we ! 11: * would use the stack upon exit from 'fork()'. ! 12: * ! 13: * Actually only pause and fork are needed inline, so that there ! 14: * won't be any messing with the stack from main(), but we define ! 15: * some others too. ! 16: */ ! 17: static inline _syscall0(int,fork) ! 18: static inline _syscall0(int,pause) ! 19: static inline _syscall0(int,setup) ! 20: static inline _syscall0(int,sync) ! 21: ! 22: #include <linux/tty.h> ! 23: #include <linux/sched.h> ! 24: #include <linux/head.h> ! 25: #include <asm/system.h> ! 26: #include <asm/io.h> ! 27: ! 28: #include <stddef.h> ! 29: #include <stdarg.h> ! 30: #include <unistd.h> ! 31: #include <fcntl.h> ! 32: #include <sys/types.h> ! 33: ! 34: #include <linux/fs.h> ! 35: ! 36: static char printbuf[1024]; ! 37: ! 38: extern int vsprintf(); ! 39: extern void init(void); ! 40: extern void hd_init(void); ! 41: extern long kernel_mktime(struct tm * tm); ! 42: extern long startup_time; ! 43: ! 44: /* ! 45: * Yeah, yeah, it's ugly, but I cannot find how to do this correctly ! 46: * and this seems to work. I anybody has more info on the real-time ! 47: * clock I'd be interested. Most of this was trial and error, and some ! 48: * bios-listing reading. Urghh. ! 49: */ ! 50: ! 51: #define CMOS_READ(addr) ({ \ ! 52: outb_p(0x80|addr,0x70); \ ! 53: inb_p(0x71); \ ! 54: }) ! 55: ! 56: #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) ! 57: ! 58: static void time_init(void) ! 59: { ! 60: struct tm time; ! 61: ! 62: do { ! 63: time.tm_sec = CMOS_READ(0); ! 64: time.tm_min = CMOS_READ(2); ! 65: time.tm_hour = CMOS_READ(4); ! 66: time.tm_mday = CMOS_READ(7); ! 67: time.tm_mon = CMOS_READ(8)-1; ! 68: time.tm_year = CMOS_READ(9); ! 69: } while (time.tm_sec != CMOS_READ(0)); ! 70: BCD_TO_BIN(time.tm_sec); ! 71: BCD_TO_BIN(time.tm_min); ! 72: BCD_TO_BIN(time.tm_hour); ! 73: BCD_TO_BIN(time.tm_mday); ! 74: BCD_TO_BIN(time.tm_mon); ! 75: BCD_TO_BIN(time.tm_year); ! 76: startup_time = kernel_mktime(&time); ! 77: } ! 78: ! 79: void main(void) /* This really IS void, no error here. */ ! 80: { /* The startup routine assumes (well, ...) this */ ! 81: /* ! 82: * Interrupts are still disabled. Do necessary setups, then ! 83: * enable them ! 84: */ ! 85: time_init(); ! 86: tty_init(); ! 87: trap_init(); ! 88: sched_init(); ! 89: buffer_init(); ! 90: hd_init(); ! 91: sti(); ! 92: move_to_user_mode(); ! 93: if (!fork()) { /* we count on this going ok */ ! 94: init(); ! 95: } ! 96: /* ! 97: * NOTE!! For any other task 'pause()' would mean we have to get a ! 98: * signal to awaken, but task0 is the sole exception (see 'schedule()') ! 99: * as task 0 gets activated at every idle moment (when no other tasks ! 100: * can run). For task0 'pause()' just means we go check if some other ! 101: * task can run, and if not we return here. ! 102: */ ! 103: for(;;) pause(); ! 104: } ! 105: ! 106: static int printf(const char *fmt, ...) ! 107: { ! 108: va_list args; ! 109: int i; ! 110: ! 111: va_start(args, fmt); ! 112: write(1,printbuf,i=vsprintf(printbuf, fmt, args)); ! 113: va_end(args); ! 114: return i; ! 115: } ! 116: ! 117: static char * argv[] = { "-",NULL }; ! 118: static char * envp[] = { "HOME=/usr/root", NULL }; ! 119: ! 120: void init(void) ! 121: { ! 122: int i,j; ! 123: ! 124: setup(); ! 125: if (!fork()) ! 126: _exit(execve("/bin/update",NULL,NULL)); ! 127: (void) open("/dev/tty0",O_RDWR,0); ! 128: (void) dup(0); ! 129: (void) dup(0); ! 130: printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS, ! 131: NR_BUFFERS*BLOCK_SIZE); ! 132: printf(" Ok.\n\r"); ! 133: if ((i=fork())<0) ! 134: printf("Fork failed in init\r\n"); ! 135: else if (!i) { ! 136: close(0);close(1);close(2); ! 137: setsid(); ! 138: (void) open("/dev/tty0",O_RDWR,0); ! 139: (void) dup(0); ! 140: (void) dup(0); ! 141: _exit(execve("/bin/sh",argv,envp)); ! 142: } ! 143: j=wait(&i); ! 144: printf("child %d died with code %04x\n",j,i); ! 145: sync(); ! 146: _exit(0); /* NOTE! _exit, not exit() */ ! 147: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.