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