[source navigation] [diff markup] [identifier search] [freetext search] [file search]

Oldlinux Cross Reference
Linux/init/main.c

Version: [1.0] [0.99.11] [0.99] [0.98] [0.97] [0.96a] [0.95] [0.12] [0.11] [0.01]
Architecture: [i386]

  1 /*
  2  *  linux/init/main.c
  3  *
  4  *  (C) 1991  Linus Torvalds
  5  */
  6 
  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)
 25 static inline _syscall1(int,setup,void *,BIOS)
 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);
 46 extern void blk_dev_init(void);
 47 extern void chr_dev_init(void);
 48 extern void hd_init(void);
 49 extern void floppy_init(void);
 50 extern void mem_init(long start, long end);
 51 extern long rd_init(long mem_start, int length);
 52 extern long kernel_mktime(struct tm * tm);
 53 extern long startup_time;
 54 
 55 /*
 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 /*
 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);
 85                 time.tm_mon = CMOS_READ(8);
 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);
 94         time.tm_mon--;
 95         startup_time = kernel_mktime(&time);
 96 }
 97 
 98 static long memory_end = 0;
 99 static long buffer_memory_end = 0;
100 static long main_memory_start = 0;
101 
102 struct drive_info { char dummy[32]; } drive_info;
103 
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  */
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;
116         if (memory_end > 12*1024*1024) 
117                 buffer_memory_end = 4*1024*1024;
118         else if (memory_end > 6*1024*1024)
119                 buffer_memory_end = 2*1024*1024;
120         else
121                 buffer_memory_end = 1*1024*1024;
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);
127         trap_init();
128         blk_dev_init();
129         chr_dev_init();
130         tty_init();
131         time_init();
132         sched_init();
133         buffer_init(buffer_memory_end);
134         hd_init();
135         floppy_init();
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 
162 static char * argv_rc[] = { "/bin/sh", NULL };
163 static char * envp_rc[] = { "HOME=/", NULL };
164 
165 static char * argv[] = { "-/bin/sh",NULL };
166 static char * envp[] = { "HOME=/usr/root", NULL };
167 
168 void init(void)
169 {
170         int pid,i;
171 
172         setup((void *) &drive_info);
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);
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();
207         }
208         _exit(0);       /* NOTE! _exit, not exit() */
209 }
210 

[source navigation] [diff markup] [identifier search] [freetext search] [file search]

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.