|
|
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.1.3 ! root 51: extern long rd_init(long mem_start, int length);
1.1 root 52: extern long kernel_mktime(struct tm * tm);
53: extern long startup_time;
54:
55: /*
1.1.1.2 root 56: * This is set up by the setup-routine at boot-time
57: */
58: #define EXT_MEM_K (*(unsigned short *)0x90002)
59: #define DRIVE_INFO (*(struct drive_info *)0x90080)
60: #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
61:
62: /*
1.1 root 63: * Yeah, yeah, it's ugly, but I cannot find how to do this correctly
64: * and this seems to work. I anybody has more info on the real-time
65: * clock I'd be interested. Most of this was trial and error, and some
66: * bios-listing reading. Urghh.
67: */
68:
69: #define CMOS_READ(addr) ({ \
70: outb_p(0x80|addr,0x70); \
71: inb_p(0x71); \
72: })
73:
74: #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
75:
76: static void time_init(void)
77: {
78: struct tm time;
79:
80: do {
81: time.tm_sec = CMOS_READ(0);
82: time.tm_min = CMOS_READ(2);
83: time.tm_hour = CMOS_READ(4);
84: time.tm_mday = CMOS_READ(7);
1.1.1.2 root 85: time.tm_mon = CMOS_READ(8);
1.1 root 86: time.tm_year = CMOS_READ(9);
87: } while (time.tm_sec != CMOS_READ(0));
88: BCD_TO_BIN(time.tm_sec);
89: BCD_TO_BIN(time.tm_min);
90: BCD_TO_BIN(time.tm_hour);
91: BCD_TO_BIN(time.tm_mday);
92: BCD_TO_BIN(time.tm_mon);
93: BCD_TO_BIN(time.tm_year);
1.1.1.2 root 94: time.tm_mon--;
1.1 root 95: startup_time = kernel_mktime(&time);
96: }
97:
1.1.1.2 root 98: static long memory_end = 0;
99: static long buffer_memory_end = 0;
1.1.1.3 ! root 100: static long main_memory_start = 0;
1.1.1.2 root 101:
102: struct drive_info { char dummy[32]; } drive_info;
103:
1.1 root 104: void main(void) /* This really IS void, no error here. */
105: { /* The startup routine assumes (well, ...) this */
106: /*
107: * Interrupts are still disabled. Do necessary setups, then
108: * enable them
109: */
1.1.1.2 root 110: ROOT_DEV = ORIG_ROOT_DEV;
111: drive_info = DRIVE_INFO;
112: memory_end = (1<<20) + (EXT_MEM_K<<10);
113: memory_end &= 0xfffff000;
114: if (memory_end > 16*1024*1024)
115: memory_end = 16*1024*1024;
1.1.1.3 ! root 116: if (memory_end > 12*1024*1024)
! 117: buffer_memory_end = 4*1024*1024;
! 118: else if (memory_end > 6*1024*1024)
1.1.1.2 root 119: buffer_memory_end = 2*1024*1024;
120: else
121: buffer_memory_end = 1*1024*1024;
1.1.1.3 ! root 122: main_memory_start = buffer_memory_end;
! 123: #ifdef RAMDISK
! 124: main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
! 125: #endif
! 126: mem_init(main_memory_start,memory_end);
1.1 root 127: trap_init();
1.1.1.2 root 128: blk_dev_init();
129: chr_dev_init();
130: tty_init();
131: time_init();
1.1 root 132: sched_init();
1.1.1.2 root 133: buffer_init(buffer_memory_end);
1.1 root 134: hd_init();
1.1.1.2 root 135: floppy_init();
1.1 root 136: sti();
137: move_to_user_mode();
138: if (!fork()) { /* we count on this going ok */
139: init();
140: }
141: /*
142: * NOTE!! For any other task 'pause()' would mean we have to get a
143: * signal to awaken, but task0 is the sole exception (see 'schedule()')
144: * as task 0 gets activated at every idle moment (when no other tasks
145: * can run). For task0 'pause()' just means we go check if some other
146: * task can run, and if not we return here.
147: */
148: for(;;) pause();
149: }
150:
151: static int printf(const char *fmt, ...)
152: {
153: va_list args;
154: int i;
155:
156: va_start(args, fmt);
157: write(1,printbuf,i=vsprintf(printbuf, fmt, args));
158: va_end(args);
159: return i;
160: }
161:
1.1.1.3 ! root 162: static char * argv_rc[] = { "/bin/sh", NULL };
! 163: static char * envp_rc[] = { "HOME=/", NULL };
! 164:
1.1.1.2 root 165: static char * argv[] = { "-/bin/sh",NULL };
1.1 root 166: static char * envp[] = { "HOME=/usr/root", NULL };
167:
168: void init(void)
169: {
1.1.1.3 ! root 170: int pid,i;
1.1 root 171:
1.1.1.2 root 172: setup((void *) &drive_info);
1.1 root 173: (void) open("/dev/tty0",O_RDWR,0);
174: (void) dup(0);
175: (void) dup(0);
176: printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
177: NR_BUFFERS*BLOCK_SIZE);
1.1.1.3 ! root 178: printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);
! 179: if (!(pid=fork())) {
! 180: close(0);
! 181: if (open("/etc/rc",O_RDONLY,0))
! 182: _exit(1);
! 183: execve("/bin/sh",argv_rc,envp_rc);
! 184: _exit(2);
! 185: }
! 186: if (pid>0)
! 187: while (pid != wait(&i))
! 188: /* nothing */;
! 189: while (1) {
! 190: if ((pid=fork())<0) {
! 191: printf("Fork failed in init\r\n");
! 192: continue;
! 193: }
! 194: if (!pid) {
! 195: close(0);close(1);close(2);
! 196: setsid();
! 197: (void) open("/dev/tty0",O_RDWR,0);
! 198: (void) dup(0);
! 199: (void) dup(0);
! 200: _exit(execve("/bin/sh",argv,envp));
! 201: }
! 202: while (1)
! 203: if (pid == wait(&i))
! 204: break;
! 205: printf("\n\rchild %d died with code %04x\n\r",pid,i);
! 206: sync();
1.1 root 207: }
208: _exit(0); /* NOTE! _exit, not exit() */
209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.