This source file includes following definitions.
- _syscall0
- sprintf
- time_init
- start_kernel
- printf
- init
1
2
3
4
5
6
7 #include <stddef.h>
8 #include <stdarg.h>
9 #include <time.h>
10
11 #include <sys/types.h>
12
13 #include <asm/system.h>
14 #include <asm/io.h>
15
16 #include <linux/fcntl.h>
17 #include <linux/config.h>
18 #include <linux/sched.h>
19 #include <linux/tty.h>
20 #include <linux/head.h>
21 #include <linux/unistd.h>
22
23
24
25
26
27
28
29
30
31
32
33
34
35 static inline _syscall0(int,fork)
36 static inline _syscall0(int,pause)
37 static inline _syscall1(int,setup,void *,BIOS)
38 static inline _syscall0(int,sync)
39 static inline _syscall0(pid_t,setsid)
40 static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
41 static inline _syscall1(int,dup,int,fd)
42 static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
43 static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
44 static inline _syscall1(int,close,int,fd)
45 static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
46
47 static inline pid_t wait(int * wait_stat)
48 {
49 return waitpid(-1,wait_stat,0);
50 }
51
52 static char printbuf[1024];
53
54 extern int vsprintf();
55 extern void init(void);
56 extern long blk_dev_init(long,long);
57 extern long chr_dev_init(long,long);
58 extern void hd_init(void);
59 extern void floppy_init(void);
60 extern void sock_init(void);
61 extern void mem_init(long start, long end);
62 extern long rd_init(long mem_start, int length);
63 extern long kernel_mktime(struct tm * tm);
64
65 #ifdef CONFIG_SCSI
66 extern void scsi_dev_init(void);
67 #endif
68
69 static int sprintf(char * str, const char *fmt, ...)
70 {
71 va_list args;
72 int i;
73
74 va_start(args, fmt);
75 i = vsprintf(str, fmt, args);
76 va_end(args);
77 return i;
78 }
79
80
81
82
83 #define EXT_MEM_K (*(unsigned short *)0x90002)
84 #define CON_ROWS ((*(unsigned short *)0x9000e) & 0xff)
85 #define CON_COLS (((*(unsigned short *)0x9000e) & 0xff00) >> 8)
86 #define DRIVE_INFO (*(struct drive_info *)0x90080)
87 #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
88
89
90
91
92
93
94
95
96 #define CMOS_READ(addr) ({ \
97 outb_p(0x80|addr,0x70); \
98 inb_p(0x71); \
99 })
100
101 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
102
103 static void time_init(void)
104 {
105 struct tm time;
106
107 do {
108 time.tm_sec = CMOS_READ(0);
109 time.tm_min = CMOS_READ(2);
110 time.tm_hour = CMOS_READ(4);
111 time.tm_mday = CMOS_READ(7);
112 time.tm_mon = CMOS_READ(8);
113 time.tm_year = CMOS_READ(9);
114 } while (time.tm_sec != CMOS_READ(0));
115 BCD_TO_BIN(time.tm_sec);
116 BCD_TO_BIN(time.tm_min);
117 BCD_TO_BIN(time.tm_hour);
118 BCD_TO_BIN(time.tm_mday);
119 BCD_TO_BIN(time.tm_mon);
120 BCD_TO_BIN(time.tm_year);
121 time.tm_mon--;
122 startup_time = kernel_mktime(&time);
123 }
124
125 static long memory_end = 0;
126 static long buffer_memory_end = 0;
127 static long main_memory_start = 0;
128 static char term[32];
129
130 static char * argv_init[] = { "/bin/init", NULL };
131 static char * envp_init[] = { "HOME=/", NULL, NULL };
132
133 static char * argv_rc[] = { "/bin/sh", NULL };
134 static char * envp_rc[] = { "HOME=/", NULL ,NULL };
135
136 static char * argv[] = { "-/bin/sh",NULL };
137 static char * envp[] = { "HOME=/usr/root", NULL, NULL };
138
139 struct drive_info { char dummy[32]; } drive_info;
140
141 void start_kernel(void)
142 {
143
144
145
146
147 ROOT_DEV = ORIG_ROOT_DEV;
148 sprintf(term, "TERM=con%dx%d", CON_COLS, CON_ROWS);
149 envp[1] = term;
150 envp_rc[1] = term;
151 envp_init[1] = term;
152 drive_info = DRIVE_INFO;
153 memory_end = (1<<20) + (EXT_MEM_K<<10);
154 memory_end &= 0xfffff000;
155 if (memory_end > 16*1024*1024)
156 memory_end = 16*1024*1024;
157 if (memory_end >= 12*1024*1024)
158 buffer_memory_end = 4*1024*1024;
159 else if (memory_end >= 6*1024*1024)
160 buffer_memory_end = 2*1024*1024;
161 else if (memory_end >= 4*1024*1024)
162 buffer_memory_end = 3*512*1024;
163 else
164 buffer_memory_end = 1*1024*1024;
165 main_memory_start = buffer_memory_end;
166 trap_init();
167 sched_init();
168 main_memory_start = chr_dev_init(main_memory_start,memory_end);
169 main_memory_start = blk_dev_init(main_memory_start,memory_end);
170 mem_init(main_memory_start,memory_end);
171 time_init();
172 printk("Linux version " UTS_RELEASE " " __DATE__ " " __TIME__ "\n");
173 buffer_init(buffer_memory_end);
174 hd_init();
175 floppy_init();
176 sock_init();
177 sti();
178 #ifdef CONFIG_SCSI
179 scsi_dev_init();
180 #endif
181 move_to_user_mode();
182 if (!fork()) {
183 init();
184 }
185
186
187
188
189
190
191
192 for(;;)
193 __asm__("int $0x80"::"a" (__NR_pause):"ax");
194 }
195
196 static int printf(const char *fmt, ...)
197 {
198 va_list args;
199 int i;
200
201 va_start(args, fmt);
202 write(1,printbuf,i=vsprintf(printbuf, fmt, args));
203 va_end(args);
204 return i;
205 }
206
207 void init(void)
208 {
209 int pid,i;
210
211 setup((void *) &drive_info);
212 (void) open("/dev/tty1",O_RDWR,0);
213 (void) dup(0);
214 (void) dup(0);
215 printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
216 NR_BUFFERS*BLOCK_SIZE);
217 printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);
218
219 execve("/etc/init",argv_init,envp_init);
220 execve("/bin/init",argv_init,envp_init);
221
222
223 if (!(pid=fork())) {
224 close(0);
225 if (open("/etc/rc",O_RDONLY,0))
226 _exit(1);
227 execve("/bin/sh",argv_rc,envp_rc);
228 _exit(2);
229 }
230 if (pid>0)
231 while (pid != wait(&i))
232 ;
233 while (1) {
234 if ((pid=fork())<0) {
235 printf("Fork failed in init\r\n");
236 continue;
237 }
238 if (!pid) {
239 close(0);close(1);close(2);
240 setsid();
241 (void) open("/dev/tty1",O_RDWR,0);
242 (void) dup(0);
243 (void) dup(0);
244 _exit(execve("/bin/sh",argv,envp));
245 }
246 while (1)
247 if (pid == wait(&i))
248 break;
249 printf("\n\rchild %d died with code %04x\n\r",pid,i);
250 sync();
251 }
252 _exit(0);
253 }