目录
Linux Platform bus Init
- 在Linux启动的时候自动调用,注册platform总线,名字为platform,并初始化总线。
代码流程
基于kernel4.19
1. start_kernel
562asmlinkage __visible void __init start_kernel(void)
563{
564 char *command_line;
565 char *after_dashes;
566
567 set_task_stack_end_magic(&init_task);
568 smp_setup_processor_id();
569 debug_objects_early_init();
570
571 cgroup_init_early();
572
573 local_irq_disable();
574 early_boot_irqs_disabled = true;
575
576 /*
577 * Interrupts are still disabled. Do necessary setups, then
578 * enable them.
579 */
580 boot_cpu_init();
581 page_address_init();
582 pr_notice("%s", linux_banner);
583 setup_arch(&command_line);
584 mm_init_cpumask(&init_mm);
585 setup_command_line(command_line);
586 setup_nr_cpu_ids();
587 setup_per_cpu_areas();
588 smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
589 boot_cpu_hotplug_init();
590
591 build_all_zonelists(NULL);
592 page_alloc_init();
593
594 pr_notice("Kernel command line: %s\n", boot_command_line);
595 /* parameters may set static keys */
596 jump_label_init();
597 parse_early_param();
598 after_dashes = parse_args("Booting kernel",
599 static_command_line, __start___param,
600 __stop___param - __start___param,
601 -1, -1, NULL, &unknown_bootoption);
602 if (!IS_ERR_OR_NULL(after_dashes))
603 parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
604 NULL, set_init_arg);
605
606 /*
607 * These use large bootmem allocations and must precede
608 * kmem_cache_init()
609 */
610 setup_log_buf(0);
611 vfs_caches_init_early();
612 sort_main_extable();
613 trap_init();
614 mm_init();
615
616 ftrace_init();
617
618 /* trace_printk can be enabled here */
619 early_trace_init();
620
621 /*
622 * Set up the scheduler prior starting any interrupts (such as the
623 * timer interrupt). Full topology setup happens at smp_init()
624 * time - but meanwhile we still have a functioning scheduler.
625 */
626 sched_init();
627 /*
628 * Disable preemption - early bootup scheduling is extremely
629 * fragile until we cpu_idle() for the first time.
630 */
631 preempt_disable();
632 if (WARN(!irqs_disabled(),
633 "Interrupts were enabled *very* early, fixing it\n"))
634 local_irq_disable();
635 radix_tree_init();
636
637 /*
638 * Set up housekeeping before setting up workqueues to allow the unbound
639 * workqueue to take non-housekeeping into account.
640 */
641 housekeeping_init();
642
643 /*
644 * Allow workqueue creation and work item queueing/cancelling
645 * early. Work item execution depends on kthreads and starts after
646 * workqueue_init().
647 */
648 workqueue_init_early();
649
650 rcu_init();
651
652 /* Trace events are available after this */
653 trace_init();
654
655 if (initcall_debug)
656 initcall_debug_enable();
657
658 context_tracking_init();
659 /* init some links before init_ISA_irqs() */
660 early_irq_init();
661 init_IRQ();
662 tick_init();
663 rcu_init_nohz();
664 init_timers();
665 hrtimers_init();
666 softirq_init();
667 timekeeping_init();
668
669 /*
670 * For best initial stack canary entropy, prepare it after:
671 * - setup_arch() for any UEFI RNG entropy and boot cmdline access
672 * - timekeeping_init() for ktime entropy used in rand_initialize()
673 * - rand_initialize() to get any arch-specific entropy like RDRAND
674 * - add_latent_entropy() to get any latent entropy
675 * - adding command line entropy
676 */
677 rand_initialize();
678 add_latent_entropy();
679 add_device_randomness(command_line, strlen(command_line));
680 boot_init_stack_canary();
681
682 time_init();
683 perf_event_init();
684 profile_init();
685 call_function_init();
686 WARN(!irqs_disabled(), "Interrupts were enabled early\n");
687
688 early_boot_irqs_disabled = false;
689 local_irq_enable();
690
691 kmem_cache_init_late();
692
693 /*
694 * HACK ALERT! This is early. We're enabling the console before
695 * we've done PCI setups etc, and console_init() must be aware of
696 * this. But we do want output early, in case something goes wrong.
697 */
698 console_init();
699 if (panic_later)
700 panic("Too many boot %s vars at `%s'", panic_later,
701 panic_param);
702
703 lockdep_init();
704
705 /*
706 * Need to run this when irqs are enabled, because it wants
707 * to self-test [hard/soft]-irqs on/off lock inversion bugs
708 * too:
709 */
710 locking_selftest();
711
712 /*
713 * This needs to be called before any devices perform DMA
714 * operations that might use the SWIOTLB bounce buffers. It will
715 * mark the bounce buffers as decrypted so that their usage will
716 * not cause "plain-text" data to be decrypted when accessed.
717 */
718 mem_encrypt_init();
719
720#ifdef CONFIG_BLK_DEV_INITRD
721 if (initrd_start && !initrd_below_start_ok &&
722 page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
723 pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",
724 page_to_pfn(virt_to_page((void *)initrd_start)),
725 min_low_pfn);
726 initrd_start = 0;
727 }
728#endif
729 kmemleak_init();
730 debug_objects_mem_init();
731 setup_per_cpu_pageset();
732 numa_policy_init();
733 acpi_early_init();
734 if (late_time_init)
735 late_time_init();
736 sched_clock_init();
737 calibrate_delay();
738 pid_idr_init();
739 anon_vma_init();
740#ifdef CONFIG_X86
741 if (efi_enabled(EFI_RUNTIME_SERVICES))
742 efi_enter_virtual_mode();
743#endif
744 thread_stack_cache_init();
745 cred_init();
746 fork_init();
747 proc_caches_init();
748 uts_ns_init();
749 buffer_init();
750 key_init();
751 security_init();
752 dbg_late_init();
753 vfs_caches_init();
754 pagecache_init();
755 signals_init();
756 seq_file_init();
757 proc_root_init();
758 nsfs_init();
759 cpuset_init();
760 cgroup_init();
761 taskstats_init_early();
762 delayacct_init();
763
764 check_bugs();
765
766 acpi_subsystem_init();
767 arch_post_acpi_subsys_init();
768 sfi_init_late();
769
770 if (efi_enabled(EFI_RUNTIME_SERVICES)) {
771 efi_free_boot_services();
772 }
773
774 /* Do the rest non-__init'ed, we're now alive */
775 rest_init();
776
777 prevent_tail_call_optimization();
778}
2. rest_init
402static noinline void __ref rest_init(void)
403{
404 struct task_struct *tsk;
405 int pid;
406
407 rcu_scheduler_starting();
408 /*
409 * We need to spawn init first so that it obtains pid 1, however
410 * the init task will end up wanting to create kthreads, which, if
411 * we schedule it before we create kthreadd, will OOPS.
412 */
413 pid = kernel_thread(kernel_init, NULL, CLONE_FS);
414 /*
415 * Pin init on the boot CPU. Task migration is not properly working
416 * until sched_init_smp() has been run. It will set the allowed
417 * CPUs for init to the non isolated CPUs.
418 */
419 rcu_read_lock();
420 tsk = find_task_by_pid_ns(pid, &init_pid_ns);
421 set_cpus_allowed_ptr(tsk, cpumask_of(smp_processor_id()));
422 rcu_read_unlock();
423
424 numa_default_policy();
425 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
426 rcu_read_lock();
427 kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
428 rcu_read_unlock();
429
430 /*
431 * Enable might_sleep() and smp_processor_id() checks.
432 * They cannot be enabled earlier because with CONFIG_PREEMPT=y
433 * kernel_thread() would trigger might_sleep() splats. With
434 * CONFIG_PREEMPT_VOLUNTARY=y the init task might have scheduled
435 * already, but it's stuck on the kthreadd_done completion.
436 */
437 system_state = SYSTEM_SCHEDULING;
438
439 complete(&kthreadd_done);
440
441 /*
442 * The boot idle thread must execute schedule()
443 * at least once to get things moving:
444 */
445 schedule_preempt_disabled();
446 /* Call into cpu_idle with preempt disabled */
447 cpu_startup_entry(CPUHP_ONLINE);
448}
3. kernel_init
1110static int __ref kernel_init(void *unused)
1111{
1112 int ret;
1113
1114 kernel_init_freeable();
1115 /* need to finish all async __init code before freeing the memory */
1116 async_synchronize_full();
1117 ftrace_free_init_mem();
1118 jump_label_invalidate_initmem();
1119 free_initmem();
1120 mark_readonly();
1121
1122 /*
1123 * Kernel mappings are now finalized - update the userspace page-table
1124 * to finalize PTI.
1125 */
1126 pti_finalize();
1127
1128 system_state = SYSTEM_RUNNING;
1129 numa_default_policy();
1130
1131 rcu_end_inkernel_boot();
1132
1133 if (ramdisk_execute_command) {
1134 ret = run_init_process(ramdisk_execute_command);
1135 if (!ret)
1136 return 0;
1137 pr_err("Failed to execute %s (error %d)\n",
1138 ramdisk_execute_command, ret);
1139 }
1140
1141 /*
1142 * We try each of these until one succeeds.
1143 *
1144 * The Bourne shell can be used instead of init if we are
1145 * trying to recover a really broken machine.
1146 */
1147 if (execute_command) {
1148 ret = run_init_process(execute_command);
1149 if (!ret)
1150 return 0;
1151 panic("Requested init %s failed (error %d).",
1152 execute_command, ret);
1153 }
1154 if (!try_to_run_init_process("/sbin/init") ||
1155 !try_to_run_init_process("/etc/init") ||
1156 !try_to_run_init_process("/bin/init") ||
1157 !try_to_run_init_process("/bin/sh"))
1158 return 0;
1159
1160 panic("No working init found. Try passing init= option to kernel. "
1161 "See Linux Documentation/admin-guide/init.rst for guidance.");
1162}
# kernel_init_freeable
1164static noinline void __init kernel_init_freeable(void)
1165{
1166 /*
1167 * Wait until kthreadd is all set-up.
1168 */
1169 wait_for_completion(&kthreadd_done);
1170
1171 /* Now the scheduler is fully set up and can do blocking allocations */
1172 gfp_allowed_mask = __GFP_BITS_MASK;
1173
1174 /*
1175 * init can allocate pages on any node
1176 */
1177 set_mems_allowed(node_states[N_MEMORY]);
1178
1179 cad_pid = task_pid(current);
1180
1181 smp_prepare_cpus(setup_max_cpus);
1182
1183 workqueue_init();
1184
1185 init_mm_internals();
1186
1187 do_pre_smp_initcalls();
1188 lockup_detector_init();
1189
1190 smp_init();
1191 sched_init_smp();
1192
1193 page_alloc_init_late();
1194 /* Initialize page ext after all struct pages are initialized. */
1195 page_ext_init();
1196
1197 do_basic_setup();
1198
1199 /* Open the /dev/console on the rootfs, this should never fail */
1200 if (ksys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
1201 pr_err("Warning: unable to open an initial console.\n");
1202
1203 (void) ksys_dup(0);
1204 (void) ksys_dup(0);
1205 /*
1206 * check if there is an early userspace init. If yes, let it do all
1207 * the work
1208 */
1209
1210 if (!ramdisk_execute_command)
1211 ramdisk_execute_command = "/init";
1212
1213 if (ksys_access((const char __user *)
1214 ramdisk_execute_command, 0) != 0) {
1215 ramdisk_execute_command = NULL;
1216 prepare_namespace();
1217 }
1218
1219 /*
1220 * Ok, we have completed the initial bootup, and
1221 * we're essentially up and running. Get rid of the
1222 * initmem segments and start the user-mode stuff..
1223 *
1224 * rootfs is available now, try loading the public keys
1225 * and default modules
1226 */
1227
1228 integrity_load_keys();
1229 load_default_modules();
1230}
1231
4. do_basic_setup
1015/*
1016 * Ok, the machine is now initialized. None of the devices
1017 * have been touched yet, but the CPU subsystem is up and
1018 * running, and memory and process management works.
1019 *
1020 * Now we can finally start doing some real work..
1021 */
1022static void __init do_basic_setup(void)
1023{
1024 cpuset_init_smp();
1025 shmem_init();
1026 driver_init();
1027 init_irq_proc();
1028 do_ctors();
1029 usermodehelper_enable();
1030 do_initcalls();
1031}
1032
5. driver_init
14/**
15 * driver_init - initialize driver model.
16 *
17 * Call the driver model init functions to initialize their
18 * subsystems. Called early from init/main.c.
19 */
20void __init driver_init(void)
21{
22 /* These are the core pieces */
23 devtmpfs_init();
24 devices_init();
25 buses_init();
26 classes_init();
27 firmware_init();
28 hypervisor_init();
29
30 /* These are also core pieces, but must come after the
31 * core core pieces.
32 */
33 of_core_init();
34 platform_bus_init();
35 cpu_dev_init();
36 memory_dev_init();
37 container_dev_init();
38}
6. platform_bus_init
1188int __init platform_bus_init(void)
1189{
1190 int error;
1191
1192 early_platform_cleanup();
1193
1194 error = device_register(&platform_bus);
1195 if (error) {
1196 put_device(&platform_bus);
1197 return error;
1198 }
1199 error = bus_register(&platform_bus_type);
1200 if (error)
1201 device_unregister(&platform_bus);
1202 of_platform_register_reconfig_notifier();
1203 return error;
1204}
1205
- 进行一些早期的平台清理
- 注册设备 (在/sys/devices/目录下建立 platform目录对应的设备对象 /sys/devices/platform/)
- 将Platform bus总线注册进系统