start_kernel
来源:互联网 发布:小蚁科技 知乎 编辑:程序博客网 时间:2024/05/17 08:11
01.void __init x86_64_start_kernel(char * real_mode_data) 02.{ 03. int i; 04. 05. /* 内核映像和模块区域映射的完整性检查 */ 06. ... 07. 08. /* clear bss before set_intr_gate with early_idt_handler */ 09. clear_bss(); 10. 11. /* Make NULL pointers segfault */ 12. zap_identity_mappings(); 13. 14. /* KERNEL_IMAGE_START = 0xffffffff80000000UL KERNEL_IMAGE_SIZE = 512M 15. * PAGE_OFFSET = 0xffff880000000000UL PAGE_SHIFT = 12 16. */ 17. max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT; 18. 19. for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) // segment.h中定义NUM_EXCEPTION_VECTORS = 32 20. set_intr_gate(i, early_idt_handler); // 往idt_table[i]数组中写入一个门描述符,处理函数是early_idt_handler 21. 22. /* struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table }; 23. * lidt汇编指令利用idt_descr变量初始化idtr寄存器,NR_VECTORS = 256 */ 24. load_idt((const struct desc_ptr *)&idt_descr); 25. 26. x86_64_start_reservations(real_mode_data); 27.} 28. 29.static void __init zap_identity_mappings(void) 30.{ 31. /* (pgd_t *)(init_mm.pgd + pgd_index(addr)) = (pgd_t)0 */ 32. pgd_t *pgd = pgd_offset_k(0UL); 33. pgd_clear(pgd); 34. 35. /* Read-Modify-Write to CR4 */ 36. __flush_tlb_all(); 37.} 38. 39.static void __init clear_bss(void) 40.{ memset(__bss_start, 0, (unsigned long) __bss_stop - (unsigned long) __bss_start); } 41. 42.static void __init copy_bootdata(char *real_mode_data) 43.{ 44. char * command_line; 45. 46. memcpy(&boot_params, real_mode_data, sizeof boot_params); 47. if (boot_params.hdr.cmd_line_ptr) { 48. command_line = __va(boot_params.hdr.cmd_line_ptr); 49. memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 50. } 51.} 52.void __init x86_64_start_reservations(char *real_mode_data) 53.{ 54. copy_bootdata(__va(real_mode_data)); 55. memblock_init(); 56. memblock_x86_reserve_range(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS"); 57. 58.#ifdef CONFIG_BLK_DEV_INITRD 59. /* Reserve INITRD */ 60. if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) { 61. /* Assume only end is not page aligned */ 62. unsigned long ramdisk_image = boot_params.hdr.ramdisk_image; 63. unsigned long ramdisk_size = boot_params.hdr.ramdisk_size; 64. unsigned long ramdisk_end = PAGE_ALIGN(ramdisk_image + ramdisk_size); 65. memblock_x86_reserve_range(ramdisk_image, ramdisk_end, "RAMDISK"); 66. } 67.#endif 68. 69. reserve_ebda_region(); 70. /* At this point everything still needed from the boot loader or BIOS or kernel text 71. * should be early reserved or marked not RAM in e820. All other memory is free game. */ 72. start_kernel(); 73.} 74. 75. 76.asmlinkage void __init start_kernel(void) 77.{ 78. char * command_line; 79. extern const struct kernel_param __start___param[], __stop___param[]; 80. 81. /* 当只有一个CPU的时候这个函数什么都不做,SMP时,返回在启动的时候的那个CPU号 */ 82. smp_setup_processor_id(); 83. 84. /* Need to run as early as possible, to initialize the lockdep hash: */ 85. lockdep_init(); 86. debug_objects_early_init(); 87. 88. /* Set up the the initial canary ASAP: */ 89. boot_init_stack_canary(); 90. cgroup_init_early(); /* 系统启动时的cgroup初始化,初始化那些要求early init的子系统 */ 91. local_irq_disable(); 92. early_boot_irqs_disabled = true; 93. /* Interrupts are still disabled. Do necessary setups, then enable them */ 94. tick_init(); 95. boot_cpu_init(); 96. /* 初始化页地址,使用链表将其链接起来 */ 97. page_address_init(); 98. printk(KERN_NOTICE "%s", linux_banner); 99. 100. /* 体系结构相关函数,由源码树顶层目录下的Makefile中的ARCH变量决定 */ 101. setup_arch(&command_line); 102. mm_init_owner(&init_mm, &init_task); /* init_mm.owner = &init_task */ 103. mm_init_cpumask(&init_mm); 104. setup_command_line(command_line); 105. setup_nr_cpu_ids(); /* nr_cpu_ids = NR_CPUS */ 106. setup_per_cpu_areas(); 107. smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ 108. 109. build_all_zonelists(NULL); 110. page_alloc_init(); 111. 112. printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); 113. 114. /* 对内核选项的两次解析 */ 115. parse_early_param(); 116. parse_args("Booting kernel", static_command_line, __start___param, 117. __stop___param - __start___param, &unknown_bootoption); 118. 119. /* These use large bootmem allocations and must precede kmem_cache_init() */ 120. setup_log_buf(0); 121. 122. /* 初始化hash表,便于从进程的PID获得对应的进程描述符指针 */ 123. pidhash_init(); 124. 125. /* 虚拟文件系统初始化,包括dcache\inode\files\mnt\bdev_cache\chrdev_init() */ 126. vfs_caches_init_early(); 127. sort_main_extable(); 128. 129. /* trap_init函数完成对系统保留中断向量(异常、非屏蔽中断以及系统调用)的初始化 130. * init_IRQ函数则完成其余中断向量的初始化 131. */ 132. trap_init(); 133. mm_init(); 134. 135. /* Set up the scheduler prior starting any interrupts (such as the 136. * timer interrupt). Full topology setup happens at smp_init() 137. * time - but meanwhile we still have a functioning scheduler. 138. */ 139. sched_init(); 140. /* 141. * Disable preemption - early bootup scheduling is extremely 142. * fragile until we cpu_idle() for the first time. 143. */ 144. preempt_disable(); 145. if (!irqs_disabled()) { 146. printk(KERN_WARNING "start_kernel(): bug: interrupts were " 147. "enabled *very* early, fixing it\n"); 148. local_irq_disable(); 149. } 150. idr_init_cache(); 151. 152. /* NOTE: */ 153. perf_event_init(); 154. 155. rcu_init(); 156. radix_tree_init(); 157. /* init some links before init_ISA_irqs() */ 158. early_irq_init(); 159. init_IRQ(); 160. prio_tree_init(); 161. 162. /* 初始化定时器相关的数据结构*/ 163. init_timers(); 164. 165. /* 对高精度时钟进行初始化 */ 166. hrtimers_init(); 167. 168. softirq_init(); 169. timekeeping_init(); 170. 171. /* 初始化系统时钟源 */ 172. time_init(); 173. 174. /* 对内核的profile功能(一个内核性能调试工具)进行初始化 */ 175. profile_init(); 176. call_function_init(); 177. if (!irqs_disabled()) 178. printk(KERN_CRIT "start_kernel(): bug: interrupts were " 179. "enabled early\n"); 180. early_boot_irqs_disabled = false; 181. local_irq_enable(); 182. 183. /* Interrupts are enabled now so all GFP allocations are safe. */ 184. gfp_allowed_mask = __GFP_BITS_MASK; 185. 186. /* slab初始化 */ 187. kmem_cache_init_late(); 188. 189. /* 190. * HACK ALERT! This is early. We're enabling the console before 191. * we've done PCI setups etc, and console_init() must be aware of 192. * this. But we do want output early, in case something goes wrong. 193. */ 194. /* 控制台初始化以显示printk的内容,在此之前调用的printk只是把数据存到缓冲区里 */ 195. console_init(); 196. if (panic_later) 197. panic(panic_later, panic_param); 198. 199. /* 如果定义了CONFIG_LOCKDEP宏,则打印锁依赖信息,否则什么也不做 */ 200. lockdep_info(); 201. 202. /* 203. * Need to run this when irqs are enabled, because it wants 204. * to self-test [hard/soft]-irqs on/off lock inversion bugs 205. * too: 206. */ 207. locking_selftest(); 208. 209.#ifdef CONFIG_BLK_DEV_INITRD 210. if (initrd_start && !initrd_below_start_ok && 211. page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { 212. printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " 213. "disabling it.\n", 214. page_to_pfn(virt_to_page((void *)initrd_start)), 215. min_low_pfn); 216. initrd_start = 0; 217. } 218.#endif 219. page_cgroup_init(); 220. enable_debug_pagealloc(); 221. debug_objects_mem_init(); 222. kmemleak_init(); 223. setup_per_cpu_pageset(); 224. numa_policy_init(); 225. if (late_time_init) 226. late_time_init(); 227. sched_clock_init(); 228. 229. /* 根据CPU在1s内执行极短循环的次数,得到BogoMIPS值 */ 230. calibrate_delay(); 231. pidmap_init(); 232. anon_vma_init(); 233.#ifdef CONFIG_X86 234. if (efi_enabled) 235. efi_enter_virtual_mode(); 236.#endif 237. thread_info_cache_init(); 238. cred_init(); 239. 240. /* 根据物理内存大小计算允许创建进程数量 */ 241. fork_init(totalram_pages); 242. proc_caches_init(); 243. buffer_init(); 244. key_init(); 245. security_init(); 246. dbg_late_init(); 247. vfs_caches_init(totalram_pages); 248. signals_init(); 249. /* rootfs populating might need page-writeback */ 250. page_writeback_init(); 251.#ifdef CONFIG_PROC_FS 252. proc_root_init(); 253.#endif 254. cgroup_init(); /* 注册cgroup文件系统并创建/proc/cgroup文件,初始化所有在cgroup_init_early中没有初始化的子系统 */ 255. cpuset_init(); 256. taskstats_init_early(); 257. delayacct_init(); 258. 259. /* 测试CPU的各种缺陷,记录检测到的缺陷,以便于内核的其他部分可以使用它们的工作 260. * check_bugs=>identify_boot_cpu=>identify_cpu会做很多工作,包括select_idle_routine以及intel_init_thermal 261. */ 262. check_bugs(); 263. 264. acpi_early_init(); /* before LAPIC and SMP init */ 265. sfi_init_late(); 266. 267. ftrace_init(); 268. 269. /* Do the rest non-__init'ed, we're now alive */ 270. /* 创建init进程 */ 271. rest_init(); 272.}
转自:http://blog.csdn.net/wlp600/article/details/6935731
- start_kernel
- start_kernel
- start_kernel
- start_kernel
- start_kernel
- start_kernel
- start_kernel()
- start_kernel 分析
- before start_kernel
- start_kernel 分析
- start_kernel分析
- start_kernel()函数
- start_kernel->build_all_zonelists
- start_kernel->mem_init
- Linux start_kernel
- start_kernel分析
- start_kernel分析
- start_kernel 转
- linux下消息队列使用
- windowsXP SP3下手动配置PHP5.4+Apache2.2.22+Mysql5.5+discuz
- WPF/MVVM 快速开始指南(译)
- css取消无序列表<ul>点用list-style:none;
- linux scsi generic howto学习笔记
- start_kernel
- linux socket 编程
- poj 3414( 搜索 )
- C++读取文件
- java MD5应用
- 小议LR中的download filter功能
- 放弃stripes
- s3c6410的UART设备驱动(3)
- linux socket read