Chinaunix首页 | 论坛 | 博客
  • 博客访问: 305647
  • 博文数量: 54
  • 博客积分: 3050
  • 博客等级: 中校
  • 技术积分: 601
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-25 16:53
文章分类
文章存档

2012年(1)

2011年(7)

2010年(46)

我的朋友

分类: LINUX

2010-01-25 20:00:39

chapter5: network device initialization.

asmlinkage void __init start_kernel(void)
{
char * command_line;
extern char saved_command_line[];
extern struct kernel_param __start___param[], __stop___param[];
/*
 * Interrupts are still disabled. Do necessary setups, then
 * enable them
 */
lock_kernel();
printk(linux_banner);
setup_arch(&command_line);
setup_per_zone_pages_min();
setup_per_cpu_areas();

/*
* Mark the boot cpu "online" so that it can call console drivers in
* printk() and can access its per-cpu storage.
*/
smp_prepare_boot_cpu();

build_all_zonelists();
page_alloc_init();
printk("Kernel command line: %s\n", saved_command_line);
parse_args("Booting kernel", command_line, __start___param,
  __stop___param - __start___param,
  &unknown_bootoption);
trap_init();
rcu_init();
init_IRQ();
pidhash_init();
sched_init();
softirq_init();
time_init();

/*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
console_init();
profile_init();
local_irq_enable();
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
initrd_start < min_low_pfn << PAGE_SHIFT) {
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
   "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
initrd_start = 0;
}
#endif
page_address_init();
mem_init();
kmem_cache_init();
if (late_time_init)
late_time_init();
calibrate_delay();
pidmap_init();
pgtable_cache_init();
pte_chain_init();
fork_init(num_physpages);
proc_caches_init();
buffer_init();
security_scaffolding_startup();
vfs_caches_init(num_physpages);
radix_tree_init();
signals_init();
/* rootfs populating might need page-writeback */
page_writeback_init();
populate_rootfs();
#ifdef CONFIG_PROC_FS
proc_root_init();
#endif
check_bugs();
printk("POSIX conformance testing by UNIFIX\n");

/* 
* We count on the initial thread going ok 
* Like idlers init is an unlocked kernel thread, which will
* make syscalls (and thus be locked).
*/
init_idle(current, smp_processor_id());

/* Do the rest non-__init'ed, we're now alive */
rest_init();
}

static void rest_init(void)
{
kernel_thread(init, NULL, CLONE_KERNEL);
unlock_kernel();
  cpu_idle();

static int init(void * unused)
{
lock_kernel();
/*
* Tell the world that we're going to be the grim
* reaper of innocent orphaned children.
*
* We don't want people to have to make incorrect
* assumptions about where in the task array this
* can be found.
*/
child_reaper = current;

/* Sets up cpus_possible() */
smp_prepare_cpus(max_cpus);

do_pre_smp_initcalls();

smp_init();
do_basic_setup();

prepare_namespace();

/*
* Ok, we have completed the initial bootup, and
* we're essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/
free_initmem();
unlock_kernel();
system_running = 1;

if (open("/dev/console", O_RDWR, 0) < 0)
printk("Warning: unable to open an initial console.\n");

(void) dup(0);
(void) dup(0);
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are 
* trying to recover a really broken machine.
*/

if (execute_command)
run_init_process(execute_command);

run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

panic("No init found.  Try passing init= option to kernel.");
}

static void __init do_basic_setup(void)
{
driver_init();

#ifdef CONFIG_SYSCTL
sysctl_init();
#endif

/* Networking initialization needs a process context */ 
sock_init();

init_workqueues();
do_initcalls();
}

static void __init do_initcalls(void)
{
    initcall_t *call;
    int count = preempt_count();

    for (call = &__initcall_start; call < &__initcall_end; call++) {
        char *msg;

        if (initcall_debug)
            printk("calling initcall 0x%p\n", *call);

        (*call)();

        msg = NULL;
        if (preempt_count() != count) {
            msg = "preemption imbalance";
            preempt_count() = count;
        }
        if (irqs_disabled()) {
            msg = "disabled interrupts";
            local_irq_enable();
        }
        if (msg) {
            printk("error in initcall at 0x%p: "
                "returned with %s\n", *call, msg);
                                                                                   510,4-16      82%
static void __init do_initcalls(void)
{
    initcall_t *call;
    int count = preempt_count();

    for (call = &__initcall_start; call < &__initcall_end; call++) {
        char *msg;

        if (initcall_debug)
            printk("calling initcall 0x%p\n", *call);

        (*call)();

        msg = NULL;
        if (preempt_count() != count) {
            msg = "preemption imbalance";
            preempt_count() = count;
        }
        if (irqs_disabled()) {
            msg = "disabled interrupts";
            local_irq_enable();
        }
        if (msg) {
            printk("error in initcall at 0x%p: "
                "returned with %s\n", *call, msg);
        }
    }

    /* Make sure there is no pending stuff from the initcall sequence */
    flush_scheduled_work();
}

阅读(1547) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~