另一个重要函数 在 start_kernel中最后调用的函数 0# 1#进程都是在这里启动的
static noinline void __init_refok rest_init(void) __releases(kernel_lock)
{
int pid;
rcu_scheduler_starting();
/*
* We need to spawn init first so that it obtains pid 1, however
* the init task will end up wanting to create kthreads, which, if
* we schedule it before we create kthreadd, will OOPS.
*/
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
numa_default_policy();
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
rcu_read_lock();
kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
rcu_read_unlock();
complete(&kthreadd_done);
unlock_kernel();
/*
* The boot idle thread must execute schedule()
* at least once to get things moving:
*/
init_idle_bootup_task(current);
preempt_enable_no_resched();
schedule();
preempt_disable();
/* Call into cpu_idle with preempt disabled */
cpu_idle();
}
static int __init kernel_init(void * unused)
{
/*
* Wait until kthreadd is all set-up. kernel_init()函数等待kthreadd_done条件完成再开始启动。
*/
wait_for_completion(&kthreadd_done);
lock_kernel();
/*
* init can allocate pages on any node.
*/
set_mems_allowed(node_states[N_HIGH_MEMORY]);
/*
* init can run on any cpu.
*/
set_cpus_allowed_ptr(current, cpu_all_mask);
/*
* 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.
*/
init_pid_ns.child_reaper = current;
/*
* When the value in this file is 0 (the default), ctrl-alt-del is trapped and sent to the init program to handle a
* graceful restart (or to the PID of your choice, which you can configure with cad_pid tunable). However, when the
* value is greater that zero, Linux's reaction to this key combination will be an immediate reboot, without syncing
* its dirty buffers.
* When a program (like dosemu) has the keyboard in raw mode, the ctrl-alt-del is intercepted by the program
* before it ever reaches the kernel tty layer, and it is up to the program to decide what to do with it.
*/
cad_pid = task_pid(current);
smp_prepare_cpus(setup_max_cpus);
do_pre_smp_initcalls();
------------------------------------
start_boot_trace();
smp_init();
------------------------------------
sched_init_smp();
do_basic_setup();
/* Open the /dev/console on the rootfs, this should never fail */
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
printk(KERN_WARNING "Warning: unable to open an initial console./n");
(void) sys_dup(0);
(void) sys_dup(0);
/*
* check if there is an early userspace init. If yes, let it do all
* the work
*/
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command = NULL;
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..
*/
init_post();
return 0;
}
static void __init do_pre_smp_initcalls(void)
{
initcall_t *fn;
for (fn = __initcall_start; fn < __early_initcall_end; fn++)
do_one_initcall(*fn);
}
c002d328 T __initcall_start
c002d328 T __setup_end
c002d32c t __initcall_spawn_softlockup_taskearly
c002d330 t __initcall_relay_initearly
c002d334 T __early_initcall_end
sched_init_smp()->sched_init_granularity()->update_sysctl()
static void update_sysctl(void)
{
unsigned int factor = get_update_sysctl_factor();
#define SET_SYSCTL(name) /
(sysctl_##name = (factor) * normalized_sysctl_##name)
SET_SYSCTL(sched_min_granularity);
SET_SYSCTL(sched_latency);
SET_SYSCTL(sched_wakeup_granularity);
SET_SYSCTL(sched_shares_ratelimit);
#undef SET_SYSCTL
}
c06863c0 D sysctl_sched_min_granularity
c06863c4 D normalized_sysctl_sched_min_granularity
c06863c8 D sysctl_sched_latency
c06863cc D normalized_sysctl_sched_latency
c06863d0 D sysctl_sched_wakeup_granularity
c06863d4 D normalized_sysctl_sched_wakeup_granularity
c06863d8 D sysctl_sched_shares_ratelimit
c06863dc D normalized_sysctl_sched_shares_ratelimit
/*
* Ok, the machine is now initialized. None of the devices
* have been touched yet, but the CPU subsystem is up and
* running, and memory and process management works.
* CPU已经running,存储器和进程管理也已工作。
* Now we can finally start doing some real work.. 开始干一些实际的工作了。。。
*/
static void __init do_basic_setup(void)
{
init_workqueues();
cpuset_init_smp();
usermodehelper_init();
init_tmpfs();
driver_init();
init_irq_proc();
do_ctors();
do_initcalls();
}
void __init usermodehelper_init(void)
{
khelper_wq = create_singlethread_workqueue("khelper");
BUG_ON(!khelper_wq);
}
Linux has various parts of the hotplug subsystem and events subsystem, which work together when a new device is inserted before it becomes available. Linux has a permanent kernel_thread helper running called khelper . This thread is occasionally used as a schedulable context for stuff that call_usermode_helper wants to run - like /sbin/hotplug or modprobe. It’s a pretty cool solution to the problem of calling out to userspace for help. khelper is responsible for running up hotplug when I insert my wifi card, which then configures the netdevice and hooks up ifplugd to watch for net events.
static void __init do_initcalls(void)
{
initcall_t *fn;
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_one_initcall(*fn);
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_work();
}
c002d328 T __initcall_start
c002d328 T __setup_end
c002d32c t __initcall_spawn_softlockup_taskearly
c002d330 t __initcall_relay_initearly
c002d334 T __early_initcall_end
c002d334 t __initcall_init_mmap_min_addr0
c002d338 t __initcall_init_cpufreq_transition_notifier_list0
c002d33c t __initcall_net_ns_init0
c002d340 t __initcall_ptrace_break_init1
c002d344 t __initcall_consistent_init1
..........................................................
c002db5c t __initcall_tcp_congestion_default7
c002db60 t __initcall_msm_pm_init7s
c002db64 t __initcall_initialize_hashrnd7s
c002db68 T __con_initcall_start
c002db68 t __initcall_con_init
c002db68 T __initcall_end
call the .init function to init the linked to kernel modules.