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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [init/] [main.c] - Blame information for rev 1772

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

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

powered by: WebSVN 2.1.0

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