OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [init/] [main.c] - Blame information for rev 743

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *  linux/init/main.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 *
6
 *  GK 2/5/95  -  Changed to support mounting root fs via NFS
7
 *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
8
 *  Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
9
 */
10
 
11
/*
12
 * Revisions, including NO_MM, CONFIG_CONSOLE, and do_shell fix
13
 * by Kenneth Albanowski <kjahds@kjahds.com>,
14
 * Copyright (C) 1997, 1998 The Silver Hammer Group, Ltd.
15
 *
16
 */
17
 
18
 
19
#define __KERNEL_SYSCALLS__
20
#include <stdarg.h>
21
/*
22
#include <asm/system.h>
23
*/
24
#include <asm/io.h>
25
 
26
#include <linux/types.h>
27
#include <linux/fcntl.h>
28
#include <linux/config.h>
29
#include <linux/sched.h>
30
#include <linux/kernel.h>
31
#include <linux/tty.h>
32
#include <linux/head.h>
33
#include <linux/unistd.h>
34
#include <linux/string.h>
35
#include <linux/timer.h>
36
#include <linux/fs.h>
37
#include <linux/ctype.h>
38
#include <linux/delay.h>
39
#include <linux/utsname.h>
40
#include <linux/ioport.h>
41
#include <linux/hdreg.h>
42
#include <linux/mm.h>
43
#include <linux/major.h>
44
#include <linux/blk.h>
45
#ifdef CONFIG_ROOT_NFS
46
#include <linux/nfs_fs.h>
47
#endif
48
#ifdef CONFIG_MTRR
49
#include <asm/mtrr.h>
50
#endif
51
#ifdef CONFIG_APM
52
#include <linux/apm_bios.h>
53
#endif
54
 
55
#include <asm/bugs.h>
56
/*int printk(const char *fmt, ...);
57
*/
58
 
59
/*
60
 * Versions of gcc older than that listed below may actually compile
61
 * and link okay, but the end product can have subtle run time bugs.
62
 * To avoid associated bogus bug reports, we flatly refuse to compile
63
 * with a gcc that is known to be too old from the very beginning.
64
 */
65
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
66
#error sorry, your GCC is too old. It builds incorrect kernels.
67
#endif
68
 
69
extern char _stext, _etext;
70
extern const char *linux_banner;
71
 
72
static char printbuf[1024];
73
 
74
extern int console_loglevel;
75
 
76
static int init(void *);
77
extern int bdflush(void *);
78
#ifndef NO_MM
79
extern int kswapd(void *);
80
extern void kswapd_setup(void);
81
#endif /* !NO_MM */
82
 
83
extern void init_IRQ(void);
84
extern void init_modules(void);
85
extern long console_init(long, long);
86
extern long kmalloc_init(long,long);
87
extern void sock_init(void);
88
extern unsigned long pci_init(unsigned long, unsigned long);
89
extern void sysctl_init(void);
90
 
91
extern void no_scroll(char *str, int *ints);
92
extern void swap_setup(char *str, int *ints);
93
extern void buff_setup(char *str, int *ints);
94
extern void panic_setup(char *str, int *ints);
95
extern void bmouse_setup(char *str, int *ints);
96
extern void msmouse_setup(char *str, int *ints);
97
extern void lp_setup(char *str, int *ints);
98
extern void eth_setup(char *str, int *ints);
99
extern void xd_setup(char *str, int *ints);
100
extern void xd_manual_geo_init(char *str, int *ints);
101
extern void floppy_setup(char *str, int *ints);
102
extern void st_setup(char *str, int *ints);
103
extern void st0x_setup(char *str, int *ints);
104
extern void advansys_setup(char *str, int *ints);
105
extern void tmc8xx_setup(char *str, int *ints);
106
extern void t128_setup(char *str, int *ints);
107
extern void pas16_setup(char *str, int *ints);
108
extern void generic_NCR5380_setup(char *str, int *intr);
109
extern void generic_NCR53C400_setup(char *str, int *intr);
110
extern void aha152x_setup(char *str, int *ints);
111
extern void aha1542_setup(char *str, int *ints);
112
extern void gdth_setup(char *str, int *ints);
113
extern void aic7xxx_setup(char *str, int *ints);
114
extern void AM53C974_setup(char *str, int *ints);
115
extern void BusLogic_Setup(char *str, int *ints);
116
extern void ncr53c8xx_setup(char *str, int *ints);
117
extern void eata2x_setup(char *str, int *ints);
118
extern void u14_34f_setup(char *str, int *ints);
119
extern void fdomain_setup(char *str, int *ints);
120
extern void in2000_setup(char *str, int *ints);
121
extern void NCR53c406a_setup(char *str, int *ints);
122
extern void sym53c416_setup(char *str, int *ints);
123
extern void wd7000_setup(char *str, int *ints);
124
extern void dc390_setup(char* str, int *ints);
125
extern void ppa_setup(char *str, int *ints);
126
extern void scsi_luns_setup(char *str, int *ints);
127
extern void sound_setup(char *str, int *ints);
128
extern void apm_setup(char *str, int *ints);
129
extern void reboot_setup(char *str, int *ints);
130
extern void video_setup(char *str, int *ints);
131
#ifdef CONFIG_CDU31A
132
extern void cdu31a_setup(char *str, int *ints);
133
#endif CONFIG_CDU31A
134
#ifdef CONFIG_MCD
135
extern void mcd_setup(char *str, int *ints);
136
#endif CONFIG_MCD
137
#ifdef CONFIG_MCDX
138
extern void mcdx_setup(char *str, int *ints);
139
#endif CONFIG_MCDX
140
#ifdef CONFIG_SBPCD
141
extern void sbpcd_setup(char *str, int *ints);
142
#endif CONFIG_SBPCD
143
#ifdef CONFIG_AZTCD
144
extern void aztcd_setup(char *str, int *ints);
145
#endif CONFIG_AZTCD
146
#ifdef CONFIG_CDU535
147
extern void sonycd535_setup(char *str, int *ints);
148
#endif CONFIG_CDU535
149
#ifdef CONFIG_GSCD
150
extern void gscd_setup(char *str, int *ints);
151
#endif CONFIG_GSCD
152
#ifdef CONFIG_CM206
153
extern void cm206_setup(char *str, int *ints);
154
#endif CONFIG_CM206
155
#ifdef CONFIG_OPTCD
156
extern void optcd_setup(char *str, int *ints);
157
#endif CONFIG_OPTCD
158
#ifdef CONFIG_SJCD
159
extern void sjcd_setup(char *str, int *ints);
160
#endif CONFIG_SJCD
161
#ifdef CONFIG_ISP16_CDI
162
extern void isp16_setup(char *str, int *ints);
163
#endif CONFIG_ISP16_CDI
164
#ifdef CONFIG_BLK_DEV_RAM
165
static void ramdisk_start_setup(char *str, int *ints);
166
static void load_ramdisk(char *str, int *ints);
167
static void prompt_ramdisk(char *str, int *ints);
168
static void ramdisk_size(char *str, int *ints);
169
#ifdef CONFIG_BLK_DEV_INITRD
170
static void no_initrd(char *s,int *ints);
171
#endif
172
#endif CONFIG_BLK_DEV_RAM
173
#ifdef CONFIG_ISDN_DRV_ICN
174
extern void icn_setup(char *str, int *ints);
175
#endif
176
#ifdef CONFIG_ISDN_DRV_HISAX
177
extern void HiSax_setup(char *str, int *ints);
178
#endif
179
#ifdef CONFIG_ISDN_DRV_PCBIT
180
extern void pcbit_setup(char *str, int *ints);
181
#endif
182
 
183
#ifdef CONFIG_ATARIMOUSE
184
extern void atari_mouse_setup (char *str, int *ints);
185
#endif
186
#ifdef CONFIG_DMASOUND
187
extern void dmasound_setup (char *str, int *ints);
188
#endif
189
#ifdef CONFIG_ATARI_SCSI
190
extern void atari_scsi_setup (char *str, int *ints);
191
#endif
192
extern void wd33c93_setup (char *str, int *ints);
193
extern void gvp11_setup (char *str, int *ints);
194
 
195
#ifdef CONFIG_CYCLADES
196
extern void cy_setup(char *str, int *ints);
197
#endif
198
#ifdef CONFIG_DIGI
199
extern void pcxx_setup(char *str, int *ints);
200
#endif
201
#ifdef CONFIG_RISCOM8
202
extern void riscom8_setup(char *str, int *ints);
203
#endif
204
#ifdef CONFIG_SPECIALIX
205
extern void specialix_setup(char *str, int *ints);
206
#endif
207
#ifdef CONFIG_BAYCOM
208
extern void baycom_setup(char *str, int *ints);
209
#endif
210
#ifdef CONFIG_LCDDMA
211
extern void lcddma_init(void);
212
#endif
213
#ifdef CONFIG_DAC0800
214
extern void dac0800_init(void);
215
#endif
216
#ifdef CONFIG_DACI2S
217
extern void daci2s_init(void);
218
#endif
219
#if defined(CONFIG_T6963_DMA) || defined(CONFIG_T6963_PIO) 
220
extern void t6963fb_init(void);
221
#endif
222
 
223
#ifdef CONFIG_PARIDE_PD
224
extern void pd_setup(char *str, int *ints);
225
#endif
226
#ifdef CONFIG_PARIDE_PF
227
extern void pf_setup(char *str, int *ints);
228
#endif
229
#ifdef CONFIG_PARIDE_PT
230
extern void pt_setup(char *str, int *ints);
231
#endif
232
#ifdef CONFIG_PARIDE_PG
233
extern void pg_setup(char *str, int *ints);
234
#endif
235
#ifdef CONFIG_PARIDE_PCD
236
extern void pcd_setup(char *str, int *ints);
237
#endif
238
#ifdef CONFIG_BLK_CPQ_DA
239
#ifdef CONFIG_BLK_CPQ_DA_EISA
240
extern void cpqarray_setup(char *str, int *ints);
241
#endif
242
#endif
243
 
244
#if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
245
extern void ipc_init(void);
246
#endif
247
 
248
/*
249
 * Boot command-line arguments
250
 */
251
#define MAX_INIT_ARGS 8
252
#define MAX_INIT_ENVS 8
253
 
254
extern void time_init(void);
255
 
256
static unsigned long memory_start = 0;
257
static unsigned long memory_end = 0;
258
 
259
int rows, cols;
260
 
261
#ifdef CONFIG_BLK_DEV_RAM
262
extern int rd_doload;           /* 1 = load ramdisk, 0 = don't load */
263
extern int rd_prompt;           /* 1 = prompt for ramdisk, 0 = don't prompt */
264
extern int rd_size;             /* Size of the ramdisk(s) */
265
extern int rd_image_start;      /* starting block # of image */
266
#ifdef CONFIG_BLK_DEV_INITRD
267
int real_root_dev;              /* MUST be int for sysctl! */
268
#endif
269
#endif
270
 
271
int root_mountflags = MS_RDONLY;
272
char *execute_command = 0;
273
 
274
int serial_debug = 0;
275
 
276
#ifdef CONFIG_ROOT_NFS
277
char nfs_root_name[NFS_ROOT_NAME_LEN] = { "default" };
278
char nfs_root_addrs[NFS_ROOT_ADDRS_LEN] = { "" };
279
#endif
280
 
281
extern void dquot_init(void);
282
 
283 743 simons
//static char * argv_init[MAX_INIT_ARGS+2] = { "ping", "10.1.1.2", NULL, };
284
static char * argv_init[MAX_INIT_ARGS+2] = { NULL, };
285 199 simons
static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
286
 
287
static char * argv_rc[] = { "/bin/sh", NULL };
288
static char * envp_rc[] = { "HOME=/", "TERM=linux", NULL };
289
 
290
static char * argv[] = { "-/bin/sh",NULL };
291
static char * envp[] = { "HOME=/usr/root", "TERM=linux", NULL };
292
 
293
char *get_options(char *str, int *ints)
294
{
295
        char *cur = str;
296
        int i=1;
297
 
298
        while (cur && isdigit(*cur) && i <= 10) {
299
                ints[i++] = simple_strtoul(cur,NULL,0);
300
                if ((cur = strchr(cur,',')) != NULL)
301
                        cur++;
302
        }
303
        ints[0] = i-1;
304
        return(cur);
305
}
306
 
307
static void profile_setup(char *str, int *ints)
308
{
309
        if (ints[0] > 0)
310
                prof_shift = (unsigned long) ints[1];
311
        else
312
#ifdef CONFIG_PROFILE_SHIFT
313
                prof_shift = CONFIG_PROFILE_SHIFT;
314
#else
315
                prof_shift = 2;
316
#endif
317
}
318
 
319
struct kernel_param {
320
        const char *str;
321
        void (*setup_func)(char *, int *);
322
} ;
323
 
324
struct kernel_param bootsetups[] = {
325
        { "reserve=", reserve_setup },
326
        { "profile=", profile_setup },
327
#ifdef CONFIG_BLK_DEV_RAM
328
        { "ramdisk_start=", ramdisk_start_setup },
329
        { "load_ramdisk=", load_ramdisk },
330
        { "prompt_ramdisk=", prompt_ramdisk },
331
        { "ramdisk=", ramdisk_size },
332
        { "ramdisk_size=", ramdisk_size },
333
#ifdef CONFIG_BLK_DEV_INITRD
334
        { "noinitrd", no_initrd },
335
#endif
336
#endif
337
        { "swap=", swap_setup },
338
        { "buff=", buff_setup },
339
        { "panic=", panic_setup },
340
#ifdef CONFIG_CONSOLE
341
        { "no-scroll", no_scroll },
342
#endif
343
#ifdef CONFIG_BUGi386
344
        { "no-hlt", no_halt },
345
        { "no387", no_387 },
346
        { "reboot=", reboot_setup },
347
#endif
348
#ifdef CONFIG_INET
349
        { "ether=", eth_setup },
350
#endif
351
#ifdef CONFIG_PRINTER
352
        { "lp=", lp_setup },
353
#endif
354
#ifdef CONFIG_SCSI
355
        { "max_scsi_luns=", scsi_luns_setup },
356
#endif
357
#ifdef CONFIG_SCSI_ADVANSYS
358
        { "advansys=", advansys_setup },
359
#endif
360
#if defined(CONFIG_BLK_DEV_HD)
361
        { "hd=", hd_setup },
362
#endif
363
#ifdef CONFIG_CHR_DEV_ST
364
        { "st=", st_setup },
365
#endif
366
#ifdef CONFIG_BUSMOUSE
367
        { "bmouse=", bmouse_setup },
368
#endif
369
#ifdef CONFIG_MS_BUSMOUSE
370
        { "msmouse=", msmouse_setup },
371
#endif
372
#ifdef CONFIG_SCSI_SEAGATE
373
        { "st0x=", st0x_setup },
374
        { "tmc8xx=", tmc8xx_setup },
375
#endif
376
#ifdef CONFIG_SCSI_T128
377
        { "t128=", t128_setup },
378
#endif
379
#ifdef CONFIG_SCSI_PAS16
380
        { "pas16=", pas16_setup },
381
#endif
382
#ifdef CONFIG_SCSI_GENERIC_NCR5380
383
        { "ncr5380=", generic_NCR5380_setup },
384
        { "ncr53c400=", generic_NCR53C400_setup },
385
#endif
386
#ifdef CONFIG_SCSI_AHA152X
387
        { "aha152x=", aha152x_setup},
388
#endif
389
#ifdef CONFIG_SCSI_AHA1542
390
        { "aha1542=", aha1542_setup},
391
#endif
392
#ifdef CONFIG_SCSI_GDTH
393
        { "gdth=", gdth_setup},
394
#endif
395
#ifdef CONFIG_SCSI_AIC7XXX
396
        { "aic7xxx=", aic7xxx_setup},
397
#endif
398
#ifdef CONFIG_SCSI_BUSLOGIC
399
        { "BusLogic=", BusLogic_Setup},
400
#endif
401
#ifdef CONFIG_SCSI_NCR53C8XX
402
        { "ncr53c8xx=", ncr53c8xx_setup},
403
#endif
404
#ifdef CONFIG_SCSI_EATA
405
        { "eata=", eata2x_setup},
406
#endif
407
#ifdef CONFIG_SCSI_U14_34F
408
        { "u14-34f=", u14_34f_setup},
409
#endif
410
#ifdef CONFIG_SCSI_AM53C974
411
        { "AM53C974=", AM53C974_setup},
412
#endif
413
#ifdef CONFIG_SCSI_NCR53C406A
414
        { "ncr53c406a=", NCR53c406a_setup},
415
#endif
416
#ifdef CONFIG_SCSI_SYM53C416
417
        { "sym53c416=", sym53c416_setup},
418
#endif
419
#ifdef CONFIG_SCSI_FUTURE_DOMAIN
420
        { "fdomain=", fdomain_setup},
421
#endif
422
#ifdef CONFIG_SCSI_IN2000
423
        { "in2000=", in2000_setup},
424
#endif
425
#ifdef CONFIG_SCSI_7000FASST
426
        { "wd7000=", wd7000_setup},
427
#endif
428
#ifdef CONFIG_SCSI_PPA
429
        { "ppa=", ppa_setup },
430
#endif
431
#if defined(CONFIG_SCSI_DC390T) && ! defined(CONFIG_SCSI_DC390T_NOGENSUPP)
432
        { "tmscsim=", dc390_setup },
433
#endif
434
#ifdef CONFIG_BLK_DEV_XD
435
        { "xd=", xd_setup },
436
        { "xd_geo=", xd_manual_geo_init },
437
#endif
438
#ifdef CONFIG_BLK_DEV_FD
439
        { "floppy=", floppy_setup },
440
#endif
441
#ifdef CONFIG_CDU31A
442
        { "cdu31a=", cdu31a_setup },
443
#endif CONFIG_CDU31A
444
#ifdef CONFIG_MCD
445
        { "mcd=", mcd_setup },
446
#endif CONFIG_MCD
447
#ifdef CONFIG_MCDX
448
        { "mcdx=", mcdx_setup },
449
#endif CONFIG_MCDX
450
#ifdef CONFIG_SBPCD
451
        { "sbpcd=", sbpcd_setup },
452
#endif CONFIG_SBPCD
453
#ifdef CONFIG_AZTCD
454
        { "aztcd=", aztcd_setup },
455
#endif CONFIG_AZTCD
456
#ifdef CONFIG_CDU535
457
        { "sonycd535=", sonycd535_setup },
458
#endif CONFIG_CDU535
459
#ifdef CONFIG_GSCD
460
        { "gscd=", gscd_setup },
461
#endif CONFIG_GSCD
462
#ifdef CONFIG_CM206
463
        { "cm206=", cm206_setup },
464
#endif CONFIG_CM206
465
#ifdef CONFIG_OPTCD
466
        { "optcd=", optcd_setup },
467
#endif CONFIG_OPTCD
468
#ifdef CONFIG_SJCD
469
        { "sjcd=", sjcd_setup },
470
#endif CONFIG_SJCD
471
#ifdef CONFIG_ISP16_CDI
472
        { "isp16=", isp16_setup },
473
#endif CONFIG_ISP16_CDI
474
#ifdef CONFIG_SOUND
475
        { "sound=", sound_setup },
476
#endif
477
#ifdef CONFIG_ISDN_DRV_ICN
478
        { "icn=", icn_setup },
479
#endif
480
#ifdef CONFIG_ISDN_DRV_HISAX
481
       { "hisax=", HiSax_setup },
482
       { "HiSax=", HiSax_setup },
483
#endif
484
#ifdef CONFIG_ISDN_DRV_PCBIT
485
        { "pcbit=", pcbit_setup },
486
#endif
487
#ifdef CONFIG_ATARIMOUSE
488
        { "atamouse=", atari_mouse_setup },
489
#endif
490
#ifdef CONFIG_DMASOUND
491
        { "dmasound=", dmasound_setup },
492
#endif
493
#ifdef CONFIG_ATARI_SCSI
494
        { "atascsi=", atari_scsi_setup },
495
#endif
496
#if defined(CONFIG_A3000_SCSI) || defined(CONFIG_A2091_SCSI) \
497
            || defined(CONFIG_GVP11_SCSI)
498
        { "wd33c93=", wd33c93_setup },
499
#endif
500
#if defined(CONFIG_GVP11_SCSI)
501
        { "gvp11=", gvp11_setup },
502
#endif
503
#ifdef CONFIG_CYCLADES
504
        { "cyclades=", cy_setup },
505
#endif
506
#ifdef CONFIG_DIGI
507
        { "digi=", pcxx_setup },
508
#endif
509
#ifdef CONFIG_RISCOM8
510
        { "riscom8=", riscom8_setup },
511
#endif
512
#ifdef CONFIG_SPECIALIX
513
        { "specialix=", specialix_setup },
514
#endif
515
#ifdef CONFIG_BAYCOM
516
        { "baycom=", baycom_setup },
517
#endif
518
#ifdef CONFIG_BLK_CPQ_DA
519
#ifdef CONFIG_BLK_CPQ_DA_EISA
520
       { "smart2=", cpqarray_setup },
521
#endif
522
#endif
523
        { 0, 0 }
524
};
525
 
526
static struct kernel_param raw_params[] = {
527
 
528
#ifdef CONFIG_PARIDE_PD
529
       { "pd.", pd_setup },
530
#endif
531
#ifdef CONFIG_PARIDE_PCD
532
       { "pcd.", pcd_setup },
533
#endif
534
#ifdef CONFIG_PARIDE_PF
535
       { "pf.", pf_setup },
536
#endif
537
#ifdef CONFIG_PARIDE_PT
538
       { "pt.", pt_setup },
539
#endif
540
#ifdef CONFIG_PARIDE_PG
541
       { "pg.", pg_setup },
542
#endif
543
#ifdef CONFIG_APM
544
        { "apm=", apm_setup },
545
#endif
546
       { 0, 0 }
547
} ;
548
 
549
 
550
#ifdef CONFIG_BLK_DEV_RAM
551
static void ramdisk_start_setup(char *str, int *ints)
552
{
553
   if (ints[0] > 0 && ints[1] >= 0)
554
      rd_image_start = ints[1];
555
}
556
 
557
static void load_ramdisk(char *str, int *ints)
558
{
559
   if (ints[0] > 0 && ints[1] >= 0)
560
      rd_doload = ints[1] & 3;
561
}
562
 
563
static void prompt_ramdisk(char *str, int *ints)
564
{
565
   if (ints[0] > 0 && ints[1] >= 0)
566
      rd_prompt = ints[1] & 1;
567
}
568
 
569
static void ramdisk_size(char *str, int *ints)
570
{
571
        if (ints[0] > 0 && ints[1] >= 0)
572
                rd_size = ints[1];
573
}
574
 
575
#endif
576
 
577
static int checksetup(char *line)
578
{
579
        int i = 0;
580
        int ints[11];
581
 
582
#ifdef CONFIG_BLK_DEV_IDE
583
        /* ide driver needs the basic string, rather than pre-processed values */
584
        if (!strncmp(line,"ide",3) || (!strncmp(line,"hd",2) && line[2] != '=')) {
585
                ide_setup(line);
586
                return 1;
587
        }
588
#endif
589
        while (bootsetups[i].str) {
590
                int n = strlen(bootsetups[i].str);
591
                if (!strncmp(line,bootsetups[i].str,n)) {
592
                        bootsetups[i].setup_func(get_options(line+n,ints), ints);
593
                        return 1;
594
                }
595
                i++;
596
        }
597
 
598
        for (i=0; raw_params[i].str; i++) {
599
                int n = strlen(raw_params[i].str);
600
                if (!strncmp(line,raw_params[i].str,n)) {
601
                        raw_params[i].setup_func(line+n, NULL);
602
                        return 1;
603
                }
604
        }
605
 
606
        return 0;
607
}
608
 
609
/* this should be approx 2 Bo*oMips to start (note initial shift), and will
610
   still work even if initially too large, it will just take slightly longer */
611
unsigned long loops_per_sec = 1;/*(1<<12);*/
612
 
613
#if defined(__SMP__) && defined(__i386__)
614
unsigned long smp_loops_per_tick = 1000000;
615
#endif
616
 
617
/* This is the number of bits of precision for the loops_per_second.  Each
618
   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
619
   better than 1% */
620
#define LPS_PREC 8
621
 
622
void calibrate_delay(void)
623
{
624
        int ticks;
625
        int loopbit;
626
        int lps_precision = LPS_PREC;
627
 
628
        loops_per_sec = (1<<12);
629
 
630
        printk("Calibrating delay loop.. ");
631
        while (loops_per_sec <<= 1) {
632
                /* wait for "start of" clock tick */
633
                ticks = jiffies;
634
                while (ticks == jiffies)
635
                        /* nothing */;
636
                /* Go .. */
637
                ticks = jiffies;
638
                __delay(loops_per_sec);
639
                ticks = jiffies - ticks;
640
                if (ticks)
641
                        break;
642
                }
643
 
644
/* Do a binary approximation to get loops_per_second set to equal one clock
645
   (up to lps_precision bits) */
646
        loops_per_sec >>= 1;
647
        loopbit = loops_per_sec;
648
        while ( lps_precision-- && (loopbit >>= 1) ) {
649
                loops_per_sec |= loopbit;
650
                ticks = jiffies;
651
                while (ticks == jiffies);
652
                ticks = jiffies;
653
                __delay(loops_per_sec);
654
                if (jiffies != ticks)   /* longer than 1 tick */
655
                        loops_per_sec &= ~loopbit;
656
        }
657
 
658
/* finally, adjust loops per second in terms of seconds instead of clocks */
659
        loops_per_sec *= HZ;
660
/* Round the value and print it */
661
        printk("ok - %lu.%02lu BogoMIPS\n",
662
                loops_per_sec/500000,
663
                (loops_per_sec/5000) % 100);
664
 
665
#if defined(__SMP__) && defined(__i386__)
666
        smp_loops_per_tick = loops_per_sec / 400;
667
#endif
668
}
669
 
670
static void parse_root_dev(char * line)
671
{
672
        int base = 0;
673
        static struct dev_name_struct {
674
                const char *name;
675
                const int num;
676
        } devices[] = {
677
                { "nfs",     0x00ff },
678
                { "loop",    0x0700 },
679
                { "hda",     0x0300 },
680
                { "hdb",     0x0340 },
681
                { "hdc",     0x1600 },
682
                { "hdd",     0x1640 },
683
                { "hde",     0x2100 },
684
                { "hdf",     0x2140 },
685
                { "hdg",     0x2200 },
686
                { "hdh",     0x2240 },
687
                { "sda",     0x0800 },
688
                { "sdb",     0x0810 },
689
                { "sdc",     0x0820 },
690
                { "sdd",     0x0830 },
691
                { "sde",     0x0840 },
692
                { "sdf",     0x0850 },
693
                { "sdg",     0x0860 },
694
                { "sdh",     0x0870 },
695
                { "sdi",     0x0880 },
696
                { "sdj",     0x0890 },
697
                { "sdk",     0x08a0 },
698
                { "sdl",     0x08b0 },
699
                { "sdm",     0x08c0 },
700
                { "sdn",     0x08d0 },
701
                { "sdo",     0x08e0 },
702
                { "sdp",     0x08f0 },
703
#ifdef CONFIG_BLK_DEV_DAC960
704
                { "rd/c0d0p",0x3000 },
705
                { "rd/c0d1p",0x3008 },
706
                { "rd/c0d2p",0x3010 },
707
                { "rd/c0d3p",0x3018 },
708
                { "rd/c0d4p",0x3020 },
709
                { "rd/c0d5p",0x3028 },
710
                { "rd/c0d6p",0x3030 },
711
                { "rd/c0d7p",0x3038 },
712
                { "rd/c0d8p",0x3040 },
713
                { "rd/c0d9p",0x3048 },
714
                { "rd/c0d10p",0x3050 },
715
                { "rd/c0d11p",0x3058 },
716
                { "rd/c0d12p",0x3060 },
717
                { "rd/c0d13p",0x3068 },
718
                { "rd/c0d14p",0x3070 },
719
                { "rd/c0d15p",0x3078 },
720
#endif
721
                { "fd",      0x0200 },
722
                { "xda",     0x0d00 },
723
                { "xdb",     0x0d40 },
724
                { "ram",     0x0100 },
725
                { "scd",     0x0b00 },
726
                { "mcd",     0x1700 },
727
                { "cdu535",  0x1800 },
728
                { "aztcd",   0x1d00 },
729
                { "cm206cd", 0x2000 },
730
                { "gscd",    0x1000 },
731
                { "sbpcd",   0x1900 },
732
                { "sonycd",  0x1800 },
733
                { "rom0",    0x1f00 },
734
                { "rom1",    0x1f01 },
735
#ifdef CONFIG_PARIDE_PD
736
                { "pda",     0x2d00 },
737
                { "pdb",     0x2d10 },
738
                { "pdc",     0x2d20 },
739
                { "pdd",     0x2d30 },
740
#endif
741
#ifdef CONFIG_PARIDE_PCD
742
                { "pcd",     0x2e00 },
743
#endif
744
#ifdef CONFIG_PARIDE_PF
745
                { "pf",      0x2f00 },
746
#endif
747
                { NULL, 0 }
748
        };
749
 
750
        if (strncmp(line,"/dev/",5) == 0) {
751
                struct dev_name_struct *dev = devices;
752
                line += 5;
753
                do {
754
                        int len = strlen(dev->name);
755
                        if (strncmp(line,dev->name,len) == 0) {
756
                                line += len;
757
                                base = dev->num;
758
                                break;
759
                        }
760
                        dev++;
761
                } while (dev->name);
762
        }
763
        ROOT_DEV = to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
764
}
765
 
766
/*
767
 * This is a simple kernel command line parsing function: it parses
768
 * the command line, and fills in the arguments/environment to init
769
 * as appropriate. Any cmd-line option is taken to be an environment
770
 * variable if it contains the character '='.
771
 *
772
 *
773
 * This routine also checks for options meant for the kernel.
774
 * These options are not given to init - they are for internal kernel use only.
775
 */
776
static void parse_options(char *line)
777
{
778
        char *next;
779
        int args, envs;
780
 
781
        if (!*line)
782
                return;
783
        args = 0;
784
        envs = 1;       /* TERM is set to 'linux' by default */
785
        next = line;
786
        while ((line = next) != NULL) {
787
                if ((next = strchr(line,' ')) != NULL)
788
                        *next++ = 0;
789
                /*
790
                 * check for kernel options first..
791
                 */
792
                if (!strncmp(line,"root=",5)) {
793
                        parse_root_dev(line+5);
794
                        continue;
795
                }
796
#ifdef CONFIG_ROOT_NFS
797
                if (!strncmp(line, "nfsroot=", 8)) {
798
                        int n;
799
                        line += 8;
800
                        ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255);
801
                        if (line[0] == '/' || line[0] == ',' || (line[0] >= '0' && line[0] <= '9')) {
802
                                strncpy(nfs_root_name, line, sizeof(nfs_root_name));
803
                                nfs_root_name[sizeof(nfs_root_name)-1] = '\0';
804
                                continue;
805
                        }
806
                        n = strlen(line) + strlen(NFS_ROOT);
807
                        if (n >= sizeof(nfs_root_name))
808
                                line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';
809
                        sprintf(nfs_root_name, NFS_ROOT, line);
810
                        continue;
811
                }
812
                if (!strncmp(line, "nfsaddrs=", 9)) {
813
                        line += 9;
814
                        strncpy(nfs_root_addrs, line, sizeof(nfs_root_addrs));
815
                        nfs_root_addrs[sizeof(nfs_root_addrs)-1] = '\0';
816
                        continue;
817
                }
818
#endif
819
                if (!strcmp(line,"ro")) {
820
                        root_mountflags |= MS_RDONLY;
821
                        continue;
822
                }
823
                if (!strcmp(line,"rw")) {
824
                        root_mountflags &= ~MS_RDONLY;
825
                        continue;
826
                }
827
                if (!strcmp(line,"debug")) {
828
                        console_loglevel = 10;
829
                        continue;
830
                }
831
                if (!strncmp(line,"init=",5)) {
832
                        line += 5;
833
                        execute_command = line;
834
                        continue;
835
                }
836
                if (checksetup(line))
837
                        continue;
838
                /*
839
                 * Then check if it's an environment variable or
840
                 * an option.
841
                 */
842
                if (strchr(line,'=')) {
843
                        if (envs >= MAX_INIT_ENVS)
844
                                break;
845
                        envp_init[++envs] = line;
846
                } else {
847
                        if (args >= MAX_INIT_ARGS)
848
                                break;
849
                        argv_init[++args] = line;
850
                }
851
        }
852
        argv_init[args+1] = NULL;
853
        envp_init[envs+1] = NULL;
854
}
855
 
856
 
857
extern void setup_arch(char **, unsigned long *, unsigned long *);
858
extern void arch_syms_export(void);
859
 
860
#ifndef __SMP__
861
 
862
/*
863
 *      Uniprocessor idle thread
864
 */
865
 
866
int cpu_idle(void *unused)
867
{
868
        for(;;) {
869
                idle();
870
        }
871
}
872
 
873
#else
874
 
875
/*
876
 *      Multiprocessor idle thread is in arch/...
877
 */
878
 
879
extern int cpu_idle(void * unused);
880
 
881
/*
882
 *      Activate a secondary processor.
883
 */
884
 
885
asmlinkage void start_secondary(void)
886
{
887
        trap_init();
888
        init_IRQ();
889
        smp_callin();
890
        cpu_idle(NULL);
891
}
892
 
893
 
894
 
895
/*
896
 *      Called by CPU#0 to activate the rest.
897
 */
898
 
899
static void smp_init(void)
900
{
901
        int i, j;
902
        smp_boot_cpus();
903
 
904
        /*
905
         *      Create the slave init tasks as sharing pid 0.
906
         *
907
         *      This should only happen if we have virtual CPU numbers
908
         *      higher than 0.
909
         */
910
 
911
        for (i=1; i<smp_num_cpus; i++)
912
        {
913
                struct task_struct *n, *p;
914
 
915
                j = cpu_logical_map[i];
916
                /*
917
                 *      We use kernel_thread for the idlers which are
918
                 *      unlocked tasks running in kernel space.
919
                 */
920
                kernel_thread(cpu_idle, NULL, CLONE_PID);
921
                /*
922
                 *      Don't assume linear processor numbering
923
                 */
924
                current_set[j]=task[i];
925
                current_set[j]->processor=j;
926
                cli();
927
                n = task[i]->next_run;
928
                p = task[i]->prev_run;
929
                nr_running--;
930
                n->prev_run = p;
931
                p->next_run = n;
932
                task[i]->next_run = task[i]->prev_run = task[i];
933
                sti();
934
        }
935
}
936
 
937
/*
938
 *      The autoprobe routines assume CPU#0 on the i386
939
 *      so we don't actually set the game in motion until
940
 *      they are finished.
941
 */
942
 
943
static void smp_begin(void)
944
{
945
        smp_threads_ready=1;
946
        smp_commence();
947
}
948
 
949
#endif
950
 
951
/*
952
 *      Activate the first processor.
953
 */
954
 
955
asmlinkage void start_kernel(void)
956
{
957
        char * command_line;
958
 
959
/*
960
 *      This little check will move.
961
 */
962
#ifdef __SMP__
963
        static int first_cpu=1;
964
 
965
        if(!first_cpu)
966
                start_secondary();
967
        first_cpu=0;
968
 
969
#endif  
970
 
971
/*
972
 * Interrupts are still disabled. Do necessary setups, then
973
 * enable them
974
 */
975
        setup_arch(&command_line, &memory_start, &memory_end);
976
        memory_start = paging_init(memory_start,memory_end);
977
        trap_init();
978
        init_IRQ();
979
        sched_init();
980
        time_init();
981
        parse_options(command_line);
982
 
983
#ifdef CONFIG_MODULES
984
        init_modules();
985
#endif
986
#ifdef CONFIG_PROFILE
987
        if (!prof_shift)
988
#ifdef CONFIG_PROFILE_SHIFT
989
                prof_shift = CONFIG_PROFILE_SHIFT;
990
#else
991
                prof_shift = 2;
992
#endif
993
#endif
994
        if (prof_shift) {
995
                prof_buffer = (unsigned int *) memory_start;
996
                /* only text is profiled */
997
                prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
998
                prof_len >>= prof_shift;
999
                memory_start += prof_len * sizeof(unsigned int);
1000
                memset(prof_buffer, 0, prof_len * sizeof(unsigned int));
1001
        }
1002
        memory_start = console_init(memory_start,memory_end);
1003
#ifdef CONFIG_PCI
1004
        memory_start = pci_init(memory_start,memory_end);
1005
#endif
1006
        memory_start = kmalloc_init(memory_start,memory_end);
1007
        sti();
1008
        calibrate_delay();
1009
        memory_start = inode_init(memory_start,memory_end);
1010
        memory_start = file_table_init(memory_start,memory_end);
1011
        memory_start = name_cache_init(memory_start,memory_end);
1012
#ifdef CONFIG_BLK_DEV_INITRD
1013
        if (initrd_start && initrd_start < memory_start) {
1014
                printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
1015
                    "disabling it.\n",initrd_start,memory_start);
1016
                initrd_start = 0;
1017
        }
1018
#endif
1019
        mem_init(memory_start,memory_end);
1020
        buffer_init();
1021
        sock_init();
1022
#if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
1023
        ipc_init();
1024
#endif
1025
        dquot_init();
1026
        arch_syms_export();
1027
        sti();
1028
        check_bugs();
1029
 
1030
#if defined(CONFIG_MTRR) && defined(__SMP__)
1031
        init_mtrr_config();
1032
#endif
1033
 
1034
        printk(linux_banner);
1035
#ifdef __SMP__
1036
        smp_init();
1037
#endif
1038
        sysctl_init();
1039
        /*
1040
         *      We count on the initial thread going ok
1041
         *      Like idlers init is an unlocked kernel thread, which will
1042
         *      make syscalls (and thus be locked).
1043
         */
1044
        kernel_thread(init, NULL, 0);
1045 582 simons
 
1046 199 simons
/*
1047
 * task[0] is meant to be used as an "idle" task: it may not sleep, but
1048
 * it might do some general things like count free pages or it could be
1049
 * used to implement a reasonable LRU algorithm for the paging routines:
1050
 * anything that can be useful, but shouldn't take time from the real
1051
 * processes.
1052
 *
1053
 * Right now task[0] just does a infinite idle loop.
1054
 */
1055
        cpu_idle(NULL);
1056
}
1057
 
1058
static int printf(const char *fmt, ...)
1059
{
1060
        va_list args;
1061
        int i;
1062
 
1063
        va_start(args, fmt);
1064
        write(1,printbuf,i=vsprintf(printbuf, fmt, args));
1065
        va_end(args);
1066
        return i;
1067
}
1068
 
1069
static int do_rc(void * rc)
1070
{
1071
        close(0);
1072
        if (open(rc,O_RDONLY,0))
1073
                return -1;
1074
        return execve("/bin/sh", argv_rc, envp_rc);
1075
}
1076
 
1077
static int do_shell(void * shell)
1078
{
1079
        close(0);close(1);close(2);
1080
        setsid();
1081
        if ((int)(open("/dev/tty1",O_RDWR,0) < 0) &&
1082
            (int)(open("/dev/ttyS0",O_RDWR,0) < 0))
1083
                printk("Unable to open an initial console for do_shell.\n");
1084 582 simons
 
1085 199 simons
        (void) dup(0);
1086
        (void) dup(0);
1087
        return execve(shell, argv, envp);
1088
}
1089
 
1090
#ifdef CONFIG_BLK_DEV_INITRD
1091
static int do_linuxrc(void * shell)
1092
{
1093
        static char *argv[] = { "linuxrc", NULL, };
1094
        close(0);close(1);close(2);
1095
        setsid();
1096
        (void) open("/dev/tty1",O_RDWR,0);
1097
        (void) dup(0);
1098
        (void) dup(0);
1099
        return execve(shell, argv, envp_init);
1100
}
1101
 
1102
static void no_initrd(char *s,int *ints)
1103
{
1104
        mount_initrd = 0;
1105
}
1106
#endif
1107
 
1108
static int init(void * unused)
1109
{
1110 582 simons
        int pid,i;
1111 199 simons
#ifdef CONFIG_BLK_DEV_INITRD
1112
        int real_root_mountflags;
1113
#endif
1114
#ifdef CONFIG_COLDFIRE
1115
        extern char console_device[];
1116
#endif
1117
        /* Launch bdflush from here, instead of the old syscall way. */
1118
        kernel_thread(bdflush, NULL, 0);
1119
        /* Start the background pageout daemon. */
1120
#ifndef NO_MM
1121
        kswapd_setup();
1122
        kernel_thread(kswapd, NULL, 0);
1123
#endif /* !NO_MM */
1124
 
1125
#ifdef CONFIG_BLK_DEV_INITRD
1126
        real_root_dev = ROOT_DEV;
1127
        real_root_mountflags = root_mountflags;
1128
        if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY;
1129
        else mount_initrd =0;
1130
#endif
1131
        setup();
1132
#ifdef CONFIG_LCDDMA
1133
        lcddma_init();
1134
#endif
1135
#ifdef CONFIG_DAC0800
1136
        dac0800_init();
1137
#endif
1138
#ifdef CONFIG_DACI2S
1139
        daci2s_init();
1140
#endif
1141
#if defined(CONFIG_T6963_DMA) || defined(CONFIG_T6963_PIO) 
1142
        t6963fb_init();
1143
#endif
1144
 
1145
#ifdef __SMP__
1146
        /*
1147
         *      With the devices probed and setup we can
1148
         *      now enter SMP mode.
1149
         */
1150
 
1151
        smp_begin();
1152
#endif  
1153
 
1154
        #ifdef CONFIG_UMSDOS_FS
1155
        {
1156
                /*
1157
                        When mounting a umsdos fs as root, we detect
1158
                        the pseudo_root (/linux) and initialise it here.
1159
                        pseudo_root is defined in fs/umsdos/inode.c
1160
                */
1161
                extern struct inode *pseudo_root;
1162
                if (pseudo_root != NULL){
1163
                        current->fs->root = pseudo_root;
1164
                        current->fs->pwd  = pseudo_root;
1165
                }
1166
        }
1167
        #endif
1168
 
1169
#ifdef CONFIG_BLK_DEV_INITRD
1170
        root_mountflags = real_root_mountflags;
1171
        if (mount_initrd && ROOT_DEV != real_root_dev && ROOT_DEV == MKDEV(RAMDISK_MAJOR,0)) {
1172
                int error;
1173 582 simons
 
1174 199 simons
        if ((open("/dev/tty1",O_RDWR,0) < 0) &&
1175
            (open("/dev/ttyS0",O_RDWR,0) < 0))
1176
                printk("Unable to open an initial console.\n");
1177
 
1178
                pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
1179
                if (pid>0)
1180
                        while (pid != wait(&i));
1181
                if (real_root_dev != MKDEV(RAMDISK_MAJOR, 0)) {
1182
                        error = change_root(real_root_dev,"/initrd");
1183
                        if (error)
1184
                                printk(KERN_ERR "Change root to /initrd: "
1185
                                    "error %d\n",error);
1186
                }
1187
        }
1188
#endif
1189
 
1190
        /*
1191
         *      This keeps serial console MUCH cleaner, but does assume
1192
         *      the console driver checks there really is a video device
1193
         *      attached (Sparc effectively does).
1194
         */
1195
#ifdef CONFIG_COLDFIRE
1196
        if (console_device[0] && (open(console_device,O_RDWR,0) >= 0)) {
1197
                /* Nothing */;
1198
        } else
1199
#endif /* CONFIG_COLDFIRE */
1200 582 simons
        if ((open("/dev/tty1",O_RDWR,0) < 0) &&
1201 199 simons
            (open("/dev/ttyS0",O_RDWR,0) < 0))
1202
                printk("Unable to open an initial console.\n");
1203 582 simons
 
1204 199 simons
        (void) dup(0);
1205
        (void) dup(0);
1206
 
1207 727 simons
#if 0
1208 743 simons
        printf("Executing ping... ");
1209
        execve("/bin/ping",argv_init,envp_init);
1210
        printf("failed\n");
1211
 
1212
        printf("Executing nano-X... ");
1213 727 simons
        execve("/bin/landmine",argv_init,envp_init);
1214 743 simons
        printf("failed\n");
1215
#endif
1216
        printf("Executing sash... ");
1217 727 simons
        execve("/bin/sash",argv_init,envp_init);
1218 743 simons
        printf("failed\n");
1219 727 simons
 
1220 199 simons
        if (!execute_command) {
1221
                execve("/etc/init",argv_init,envp_init);
1222
                execve("/bin/init",argv_init,envp_init);
1223
                execve("/sbin/init",argv_init,envp_init);
1224
                /* if this fails, fall through to original stuff */
1225
 
1226
                pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD);
1227
                if (pid>0)
1228
                        while (pid != wait(&i))
1229
                                /* nothing */;
1230
        }
1231
 
1232
        while (1) {
1233
                pid = kernel_thread(do_shell,
1234
                        execute_command ? execute_command : "/bin/sh",
1235
                        SIGCHLD);
1236
                if (pid < 0) {
1237
                        printf("Fork failed in init\n\r");
1238
                        continue;
1239
                }
1240
                while (1)
1241
                        if (pid == wait(&i))
1242
                                break;
1243
                printf("\n\rchild %d died with code %04x\n\r",pid,i);
1244
                sync();
1245
        }
1246
        return -1;
1247
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.