Linux内核的启动简述
来源:互联网 发布:cf最新刷枪软件 编辑:程序博客网 时间:2024/05/22 15:53
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
回顾知识:
操作系统法宝:堆栈,中断上下文切换,进程上下文切换
Linux源代码目录 linux-3.18.6
主要目录介绍:
arch不同的CPU体系结构相关的代码,主要研究x86目录Documentation相关文档drivers驱动相关代码fs文件系统相关代码init内核启动相关代码,其中main.c的start_kernel是系统启动的入口Kernel内核相关代码mm内存管理相关代码net网络相关代码gdb命令
c 继续执行(continue)
list 查看代码
break 设置断点
调试内核
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:# -S freeze CPU at startup (use ’c’ to start execution)# -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
gdb(gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表(gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行(gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后
kernel_init中完成初始化操作
9500asmlinkage __visible void __init start_kernel(void)501{502char *command_line;503char *after_dashes;504505/*506 * Need to run as early as possible, to initialize the507 * lockdep hash:508 */509lockdep_init();510set_task_stack_end_magic(&init_task);511smp_setup_processor_id();512debug_objects_early_init();513514/*515 * Set up the the initial canary ASAP:516 */517boot_init_stack_canary();518519cgroup_init_early();520521local_irq_disable();522early_boot_irqs_disabled = true;523524/*525 * Interrupts are still disabled. Do necessary setups, then526 * enable them527 */528boot_cpu_init();529page_address_init();530pr_notice("%s", linux_banner);531setup_arch(&command_line);532mm_init_cpumask(&init_mm);533setup_command_line(command_line);534setup_nr_cpu_ids();535setup_per_cpu_areas();536smp_prepare_boot_cpu();/* arch-specific boot-cpu hooks */537538build_all_zonelists(NULL, NULL);539page_alloc_init();540541pr_notice("Kernel command line: %s\n", boot_command_line);542parse_early_param();543after_dashes = parse_args("Booting kernel",544 static_command_line, __start___param,545 __stop___param - __start___param,546 -1, -1, &unknown_bootoption);547if (!IS_ERR_OR_NULL(after_dashes))548parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,549 set_init_arg);550551jump_label_init();552553/*554 * These use large bootmem allocations and must precede555 * kmem_cache_init()556 */557setup_log_buf(0);558pidhash_init();559vfs_caches_init_early();560sort_main_extable();561trap_init();562mm_init();563564/*565 * Set up the scheduler prior starting any interrupts (such as the566 * timer interrupt). Full topology setup happens at smp_init()567 * time - but meanwhile we still have a functioning scheduler.568 */569sched_init();570/*571 * Disable preemption - early bootup scheduling is extremely572 * fragile until we cpu_idle() for the first time.573 */574preempt_disable();575if (WARN(!irqs_disabled(),576 "Interrupts were enabled *very* early, fixing it\n"))577local_irq_disable();578idr_init_cache();579rcu_init();580context_tracking_init();581radix_tree_init();582/* init some links before init_ISA_irqs() */583early_irq_init();584init_IRQ();585tick_init();586rcu_init_nohz();587init_timers();588hrtimers_init();589softirq_init();590timekeeping_init();591time_init();592sched_clock_postinit();593perf_event_init();594profile_init();595call_function_init();596WARN(!irqs_disabled(), "Interrupts were enabled early\n");597early_boot_irqs_disabled = false;598local_irq_enable();599600kmem_cache_init_late();601602/*603 * HACK ALERT! This is early. We're enabling the console before604 * we've done PCI setups etc, and console_init() must be aware of605 * this. But we do want output early, in case something goes wrong.606 */607console_init();608if (panic_later)609panic("Too many boot %s vars at `%s'", panic_later,610 panic_param);611612lockdep_info();613614/*615 * Need to run this when irqs are enabled, because it wants616 * to self-test [hard/soft]-irqs on/off lock inversion bugs617 * too:618 */619locking_selftest();620621#ifdef CONFIG_BLK_DEV_INITRD622if (initrd_start && !initrd_below_start_ok &&623 page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {624pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",625 page_to_pfn(virt_to_page((void *)initrd_start)),626 min_low_pfn);627initrd_start = 0;628}629#endif630page_cgroup_init();631debug_objects_mem_init();632kmemleak_init();633setup_per_cpu_pageset();634numa_policy_init();635if (late_time_init)636late_time_init();637sched_clock_init();638calibrate_delay();639pidmap_init();640anon_vma_init();641acpi_early_init();642#ifdef CONFIG_X86643if (efi_enabled(EFI_RUNTIME_SERVICES))644efi_enter_virtual_mode();645#endif646#ifdef CONFIG_X86_ESPFIX64647/* Should be run before the first non-init thread is created */648init_espfix_bsp();649#endif650thread_info_cache_init();651cred_init();652fork_init(totalram_pages);653proc_caches_init();654buffer_init();655key_init();656security_init();657dbg_late_init();658vfs_caches_init(totalram_pages);659signals_init();660/* rootfs populating might need page-writeback */661page_writeback_init();662proc_root_init();663cgroup_init();664cpuset_init();665taskstats_init_early();666delayacct_init();667668check_bugs();669670sfi_init_late();671672if (efi_enabled(EFI_RUNTIME_SERVICES)) {673efi_late_init();674efi_free_boot_services();675}676677ftrace_init();678679/* Do the rest non-__init'ed, we're now alive */680rest_init();681}
trap_init : 中断向量的初始化工作
set_intr_gate : 设置中断门
set_system_trap_gate : 系统调用中断
393static noinline void __init_refok rest_init(void)394{395int pid;396397rcu_scheduler_starting();398/*399 * We need to spawn init first so that it obtains pid 1, however400 * the init task will end up wanting to create kthreads, which, if401 * we schedule it before we create kthreadd, will OOPS.402 */403kernel_thread(kernel_init, NULL, CLONE_FS);404numa_default_policy();405pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);406rcu_read_lock();407kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);408rcu_read_unlock();409complete(&kthreadd_done);410411/*412 * The boot idle thread must execute schedule()413 * at least once to get things moving:414 */415init_idle_bootup_task(current);416schedule_preempt_disabled();417/* Call into cpu_idle with preempt disabled */418cpu_startup_entry(CPUHP_ONLINE);419}
reset_init : 0进程初始化工作
kernel_init : 1号进程(用户态)初始化
Linux中1号进程是由0号进程来创建的,因此必须要知道的是如何创建0号进程,由于在创建进程时,程序一直运行在内核态,而进程运行在用户态,因此创建0号进程涉及到特权级的变化,即从特权级0变到特权级3,Linux是通过模拟中断返回来实现特权级的变化以及创建0号进程,通过将0号进程的代码段选择子以及程序计数器EIP直接压入内核态堆栈,然后利用iret汇编指令中断返回跳转到0号进程运行。
0 0
- Linux内核的启动简述
- Linux内核Makefile简述
- linux内核移植简述
- linux内核移植简述
- linux启动过程简述
- 简述linux启动过程
- Linux的内核启动参数
- Linux的内核启动参数
- 2.6linux内核的启动
- linux内核启动的优化
- linux 的内核启动管理
- linux内核启动的优化
- linux 内核的启动构架
- linux内核的启动流程
- linux 内核的启动部分
- linux的内核启动分析
- Linux内核的启动过程
- 跟踪linux内核的启动
- 经典迷宫问题 BFS 广度优先
- linux内核umount源代码分析
- Hdu 1069 Monkey and Banana 动态规划
- 隔离级别(Isolation Level)
- 2015年大二上-数据结构-内部排序-(4)-快速排序
- Linux内核的启动简述
- Hadoop-Windows下的Eclipse开发环境搭建,远程虚拟机Hadoop服务器
- HDU-4277 USACO ORZ
- linux中查找命令find、locate、whereis、which、type区别
- mysql索引的类型和优缺点
- Java工程项目开发中异常处理的方法及系统
- linux 下CA服务器安装
- day12—JavaScript基础
- linux安全之TCP Wrappers