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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [init/] [main.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 1275 phoenix
/*
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
 *  Simplified starting of init:  Michael A. Griffith <grif@acm.org>
10
 */
11
 
12
#define __KERNEL_SYSCALLS__
13
 
14
#include <linux/config.h>
15
#include <linux/proc_fs.h>
16
#include <linux/devfs_fs_kernel.h>
17
#include <linux/unistd.h>
18
#include <linux/string.h>
19
#include <linux/ctype.h>
20
#include <linux/delay.h>
21
#include <linux/utsname.h>
22
#include <linux/ioport.h>
23
#include <linux/init.h>
24
#include <linux/smp_lock.h>
25
#include <linux/blk.h>
26
#include <linux/hdreg.h>
27
#include <linux/iobuf.h>
28
#include <linux/bootmem.h>
29
#include <linux/file.h>
30
#include <linux/tty.h>
31
 
32
#include <asm/io.h>
33
#include <asm/bugs.h>
34
 
35
#if defined(CONFIG_ARCH_S390)
36
#include <asm/s390mach.h>
37
#include <asm/ccwcache.h>
38
#endif
39
 
40
#ifdef CONFIG_ACPI
41
#include <linux/acpi.h>
42
#endif
43
 
44
#ifdef CONFIG_PCI
45
#include <linux/pci.h>
46
#endif
47
 
48
#ifdef CONFIG_DIO
49
#include <linux/dio.h>
50
#endif
51
 
52
#ifdef CONFIG_ZORRO
53
#include <linux/zorro.h>
54
#endif
55
 
56
#ifdef CONFIG_MTRR
57
#  include <asm/mtrr.h>
58
#endif
59
 
60
#ifdef CONFIG_NUBUS
61
#include <linux/nubus.h>
62
#endif
63
 
64
#ifdef CONFIG_ISAPNP
65
#include <linux/isapnp.h>
66
#endif
67
 
68
#ifdef CONFIG_IRDA
69
extern int irda_proto_init(void);
70
extern int irda_device_init(void);
71
#endif
72
 
73
#ifdef CONFIG_X86_LOCAL_APIC
74
#include <asm/smp.h>
75
#endif
76
 
77
/*
78
 * Versions of gcc older than that listed below may actually compile
79
 * and link okay, but the end product can have subtle run time bugs.
80
 * To avoid associated bogus bug reports, we flatly refuse to compile
81
 * with a gcc that is known to be too old from the very beginning.
82
 */
83
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)
84
#error Sorry, your GCC is too old. It builds incorrect kernels.
85
#endif
86
 
87
extern char _stext, _etext;
88
extern char *linux_banner;
89
 
90
static int init(void *);
91
 
92
extern void init_IRQ(void);
93
extern void init_modules(void);
94
extern void sock_init(void);
95
extern void fork_init(unsigned long);
96
extern void mca_init(void);
97
extern void sbus_init(void);
98
extern void ppc_init(void);
99
extern void sysctl_init(void);
100
extern void signals_init(void);
101
extern int init_pcmcia_ds(void);
102
 
103
extern void free_initmem(void);
104
 
105
#ifdef CONFIG_TC
106
extern void tc_init(void);
107
#endif
108
 
109
extern void ecard_init(void);
110
 
111
#if defined(CONFIG_SYSVIPC)
112
extern void ipc_init(void);
113
#endif
114
 
115
/*
116
 * Boot command-line arguments
117
 */
118
#define MAX_INIT_ARGS 8
119
#define MAX_INIT_ENVS 8
120
 
121
extern void time_init(void);
122
extern void softirq_init(void);
123
 
124
int rows, cols;
125
 
126
char *execute_command;
127
 
128
static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
129
char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
130
 
131
static int __init profile_setup(char *str)
132
{
133
    int par;
134
    if (get_option(&str,&par)) prof_shift = par;
135
        return 1;
136
}
137
 
138
__setup("profile=", profile_setup);
139
 
140
static int __init checksetup(char *line)
141
{
142
        struct kernel_param *p;
143
 
144
        p = &__setup_start;
145
        do {
146
                int n = strlen(p->str);
147
                if (!strncmp(line,p->str,n)) {
148
                        if (p->setup_func(line+n))
149
                                return 1;
150
                }
151
                p++;
152
        } while (p < &__setup_end);
153
        return 0;
154
}
155
 
156
/* this should be approx 2 Bo*oMips to start (note initial shift), and will
157
   still work even if initially too large, it will just take slightly longer */
158
unsigned long loops_per_jiffy = (1<<12);
159
 
160
/* This is the number of bits of precision for the loops_per_jiffy.  Each
161
   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
162
   better than 1% */
163
#define LPS_PREC 8
164
 
165
void __init calibrate_delay(void)
166
{
167
        unsigned long ticks, loopbit;
168
        int lps_precision = LPS_PREC;
169
 
170
        loops_per_jiffy = (1<<12);
171
 
172
        printk("Calibrating delay loop... ");
173
        while (loops_per_jiffy <<= 1) {
174
                /* wait for "start of" clock tick */
175
                ticks = jiffies;
176
                while (ticks == jiffies)
177
                        /* nothing */;
178
                /* Go .. */
179
                ticks = jiffies;
180
                __delay(loops_per_jiffy);
181
                ticks = jiffies - ticks;
182
                if (ticks)
183
                        break;
184
        }
185
 
186
/* Do a binary approximation to get loops_per_jiffy set to equal one clock
187
   (up to lps_precision bits) */
188
        loops_per_jiffy >>= 1;
189
        loopbit = loops_per_jiffy;
190
        while ( lps_precision-- && (loopbit >>= 1) ) {
191
                loops_per_jiffy |= loopbit;
192
                ticks = jiffies;
193
                while (ticks == jiffies);
194
                ticks = jiffies;
195
                __delay(loops_per_jiffy);
196
                if (jiffies != ticks)   /* longer than 1 tick */
197
                        loops_per_jiffy &= ~loopbit;
198
        }
199
 
200
/* Round the value and print it */
201
        printk("%lu.%02lu BogoMIPS\n",
202
                loops_per_jiffy/(500000/HZ),
203
                (loops_per_jiffy/(5000/HZ)) % 100);
204
}
205
 
206
static int __init debug_kernel(char *str)
207
{
208
        if (*str)
209
                return 0;
210
        console_loglevel = 10;
211
        return 1;
212
}
213
 
214
static int __init quiet_kernel(char *str)
215
{
216
        if (*str)
217
                return 0;
218
        console_loglevel = 4;
219
        return 1;
220
}
221
 
222
__setup("debug", debug_kernel);
223
__setup("quiet", quiet_kernel);
224
 
225
/*
226
 * This is a simple kernel command line parsing function: it parses
227
 * the command line, and fills in the arguments/environment to init
228
 * as appropriate. Any cmd-line option is taken to be an environment
229
 * variable if it contains the character '='.
230
 *
231
 * This routine also checks for options meant for the kernel.
232
 * These options are not given to init - they are for internal kernel use only.
233
 */
234
static void __init parse_options(char *line)
235
{
236
        char *next,*quote;
237
        int args, envs;
238
 
239
        if (!*line)
240
                return;
241
        args = 0;
242
        envs = 1;       /* TERM is set to 'linux' by default */
243
        next = line;
244
        while ((line = next) != NULL) {
245
                quote = strchr(line,'"');
246
                next = strchr(line, ' ');
247
                while (next != NULL && quote != NULL && quote < next) {
248
                        /* we found a left quote before the next blank
249
                         * now we have to find the matching right quote
250
                         */
251
                        next = strchr(quote+1, '"');
252
                        if (next != NULL) {
253
                                quote = strchr(next+1, '"');
254
                                next = strchr(next+1, ' ');
255
                        }
256
                }
257
                if (next != NULL)
258
                        *next++ = 0;
259
                if (!strncmp(line,"init=",5)) {
260
                        line += 5;
261
                        execute_command = line;
262
                        /* In case LILO is going to boot us with default command line,
263
                         * it prepends "auto" before the whole cmdline which makes
264
                         * the shell think it should execute a script with such name.
265
                         * So we ignore all arguments entered _before_ init=... [MJ]
266
                         */
267
                        args = 0;
268
                        continue;
269
                }
270
                if (checksetup(line))
271
                        continue;
272
 
273
                /*
274
                 * Then check if it's an environment variable or
275
                 * an option.
276
                 */
277
                if (strchr(line,'=')) {
278
                        if (envs >= MAX_INIT_ENVS)
279
                                break;
280
                        envp_init[++envs] = line;
281
                } else {
282
                        if (args >= MAX_INIT_ARGS)
283
                                break;
284
                        if (*line)
285
                                argv_init[++args] = line;
286
                }
287
        }
288
        argv_init[args+1] = NULL;
289
        envp_init[envs+1] = NULL;
290
}
291
 
292
 
293
extern void setup_arch(char **);
294
extern void cpu_idle(void);
295
 
296
unsigned long wait_init_idle;
297
 
298
#ifndef CONFIG_SMP
299
 
300
#ifdef CONFIG_X86_LOCAL_APIC
301
static void __init smp_init(void)
302
{
303
        APIC_init_uniprocessor();
304
}
305
#else
306
#define smp_init()      do { } while (0)
307
#endif
308
 
309
#else
310
 
311
 
312
/* Called by boot processor to activate the rest. */
313
static void __init smp_init(void)
314
{
315
        /* Get other processors into their bootup holding patterns. */
316
        smp_boot_cpus();
317
        wait_init_idle = cpu_online_map;
318
        clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */
319
 
320
        smp_threads_ready=1;
321
        smp_commence();
322
 
323
        /* Wait for the other cpus to set up their idle processes */
324
        printk("Waiting on wait_init_idle (map = 0x%lx)\n", wait_init_idle);
325
        while (wait_init_idle) {
326
                cpu_relax();
327
                barrier();
328
        }
329
        printk("All processors have done init_idle\n");
330
}
331
 
332
#endif
333
 
334
/*
335
 * We need to finalize in a non-__init function or else race conditions
336
 * between the root thread and the init thread may cause start_kernel to
337
 * be reaped by free_initmem before the root thread has proceeded to
338
 * cpu_idle.
339
 */
340
 
341
static void rest_init(void)
342
{
343
        kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
344
        unlock_kernel();
345
        current->need_resched = 1;
346
        cpu_idle();
347
}
348
 
349
/*
350
 *      Activate the first processor.
351
 */
352
 
353
asmlinkage void __init start_kernel(void)
354
{
355
        char * command_line;
356
        extern char saved_command_line[];
357
/*
358
 * Interrupts are still disabled. Do necessary setups, then
359
 * enable them
360
 */
361
        lock_kernel();
362
        printk(linux_banner);
363
        setup_arch(&command_line);
364
        printk("Kernel command line: %s\n", saved_command_line);
365
        parse_options(command_line);
366
        trap_init();
367
        init_IRQ();
368
        sched_init();
369
        softirq_init();
370
        time_init();
371
 
372
        /*
373
         * HACK ALERT! This is early. We're enabling the console before
374
         * we've done PCI setups etc, and console_init() must be aware of
375
         * this. But we do want output early, in case something goes wrong.
376
         */
377
        console_init();
378
#ifdef CONFIG_MODULES
379
        init_modules();
380
#endif
381
        if (prof_shift) {
382
                unsigned int size;
383
                /* only text is profiled */
384
                prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
385
                prof_len >>= prof_shift;
386
 
387
                size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;
388
                prof_buffer = (unsigned int *) alloc_bootmem(size);
389
        }
390
 
391
        kmem_cache_init();
392
        sti();
393
        calibrate_delay();
394
#ifdef CONFIG_BLK_DEV_INITRD
395
        if (initrd_start && !initrd_below_start_ok &&
396
                        initrd_start < min_low_pfn << PAGE_SHIFT) {
397
                printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
398
                    "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
399
                initrd_start = 0;
400
        }
401
#endif
402
        mem_init();
403
        kmem_cache_sizes_init();
404
        pgtable_cache_init();
405
 
406
        /*
407
         * For architectures that have highmem, num_mappedpages represents
408
         * the amount of memory the kernel can use.  For other architectures
409
         * it's the same as the total pages.  We need both numbers because
410
         * some subsystems need to initialize based on how much memory the
411
         * kernel can use.
412
         */
413
        if (num_mappedpages == 0)
414
                num_mappedpages = num_physpages;
415
 
416
        fork_init(num_mappedpages);
417
        proc_caches_init();
418
        vfs_caches_init(num_physpages);
419
        buffer_init(num_physpages);
420
        page_cache_init(num_physpages);
421
#if defined(CONFIG_ARCH_S390)
422
        ccwcache_init();
423
#endif
424
        signals_init();
425
#ifdef CONFIG_PROC_FS
426
        proc_root_init();
427
#endif
428
        check_bugs();
429
        printk("POSIX conformance testing by UNIFIX\n");
430
 
431
        /*
432
         *      We count on the initial thread going ok
433
         *      Like idlers init is an unlocked kernel thread, which will
434
         *      make syscalls (and thus be locked).
435
         */
436
        smp_init();
437
#if defined(CONFIG_SYSVIPC)
438
        ipc_init();
439
#endif
440
        rest_init();
441
}
442
 
443
struct task_struct *child_reaper = &init_task;
444
 
445
static void __init do_initcalls(void)
446
{
447
        initcall_t *call;
448
 
449
        call = &__initcall_start;
450
        do {
451
                (*call)();
452
                call++;
453
        } while (call < &__initcall_end);
454
 
455
        /* Make sure there is no pending stuff from the initcall sequence */
456
        flush_scheduled_tasks();
457
}
458
 
459
/*
460
 * Ok, the machine is now initialized. None of the devices
461
 * have been touched yet, but the CPU subsystem is up and
462
 * running, and memory and process management works.
463
 *
464
 * Now we can finally start doing some real work..
465
 */
466
static void __init do_basic_setup(void)
467
{
468
 
469
        /*
470
         * Tell the world that we're going to be the grim
471
         * reaper of innocent orphaned children.
472
         *
473
         * We don't want people to have to make incorrect
474
         * assumptions about where in the task array this
475
         * can be found.
476
         */
477
        child_reaper = current;
478
 
479
#if defined(CONFIG_MTRR)        /* Do this after SMP initialization */
480
/*
481
 * We should probably create some architecture-dependent "fixup after
482
 * everything is up" style function where this would belong better
483
 * than in init/main.c..
484
 */
485
        mtrr_init();
486
#endif
487
 
488
#ifdef CONFIG_SYSCTL
489
        sysctl_init();
490
#endif
491
 
492
        /*
493
         * Ok, at this point all CPU's should be initialized, so
494
         * we can start looking into devices..
495
         */
496
#if defined(CONFIG_ARCH_S390)
497
        s390_init_machine_check();
498
#endif
499
#ifdef CONFIG_ACPI_INTERPRETER
500
        acpi_init();
501
#endif
502
#ifdef CONFIG_PCI
503
        pci_init();
504
#endif
505
#ifdef CONFIG_SBUS
506
        sbus_init();
507
#endif
508
#if defined(CONFIG_PPC)
509
        ppc_init();
510
#endif
511
#ifdef CONFIG_MCA
512
        mca_init();
513
#endif
514
#ifdef CONFIG_ARCH_ACORN
515
        ecard_init();
516
#endif
517
#ifdef CONFIG_ZORRO
518
        zorro_init();
519
#endif
520
#ifdef CONFIG_DIO
521
        dio_init();
522
#endif
523
#ifdef CONFIG_NUBUS
524
        nubus_init();
525
#endif
526
#ifdef CONFIG_ISAPNP
527
        isapnp_init();
528
#endif
529
#ifdef CONFIG_TC
530
        tc_init();
531
#endif
532
 
533
        /* Networking initialization needs a process context */
534
        sock_init();
535
 
536
        start_context_thread();
537
        do_initcalls();
538
 
539
#ifdef CONFIG_IRDA
540
        irda_proto_init();
541
        irda_device_init(); /* Must be done after protocol initialization */
542
#endif
543
#ifdef CONFIG_PCMCIA
544
        init_pcmcia_ds();               /* Do this last */
545
#endif
546
}
547
 
548
static void run_init_process(char *init_filename)
549
{
550
        argv_init[0] = init_filename;
551
        execve(init_filename, argv_init, envp_init);
552
}
553
 
554
extern void prepare_namespace(void);
555
 
556
static int init(void * unused)
557
{
558
        struct files_struct *files;
559
        lock_kernel();
560
        do_basic_setup();
561
 
562
        prepare_namespace();
563
 
564
        /*
565
         * Ok, we have completed the initial bootup, and
566
         * we're essentially up and running. Get rid of the
567
         * initmem segments and start the user-mode stuff..
568
         */
569
        free_initmem();
570
        unlock_kernel();
571
 
572
        /*
573
         * Right now we are a thread sharing with a ton of kernel
574
         * stuff. We don't want to end up in user space in that state
575
         */
576
 
577
        files = current->files;
578
        if(unshare_files())
579
                panic("unshare");
580
        put_files_struct(files);
581
 
582
        if (open("/dev/console", O_RDWR, 0) < 0)
583
                printk("Warning: unable to open an initial console.\n");
584
 
585
        (void) dup(0);
586
        (void) dup(0);
587
 
588
        /*
589
         * We try each of these until one succeeds.
590
         *
591
         * The Bourne shell can be used instead of init if we are
592
         * trying to recover a really broken machine.
593
         */
594
 
595
        if (execute_command)
596
                run_init_process(execute_command);
597
 
598
        run_init_process("/sbin/init");
599
        run_init_process("/etc/init");
600
        run_init_process("/bin/init");
601
        run_init_process("/bin/sh");
602
 
603
        panic("No init found.  Try passing init= option to kernel.");
604
}

powered by: WebSVN 2.1.0

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