Linux移植之内核启动过程start_kernel函数简析

发布者:温暖阳光最新更新时间:2024-08-26 来源: cnblogs关键字:Linux移植  start_kernel函数 手机看文章 扫描二维码
随时随地手机看文章

224     

225 /*if判断中断是否打开,如果已经打开,打印数据*/   

226 if (!irqs_disabled()) 

227     printk(KERN_CRIT 'start_kernel(): bug: interrupts were enabled early/n'); 

228 

229 //与开始的early_boot_irqs_off相对应  

230 early_boot_irqs_on(); 

231  

232 //与local_irq_disbale相对应,开CPU中断  

233 local_irq_enable();

234 

235 /*

236 * HACK ALERT! This is early. We're enabling the console before

237 * we've done PCI setups etc, and console_init() must be aware of

238 * this. But we do want output early, in case something goes wrong.

239 */ 

240 //初始化控制台以显示printk的内容,在此之前调用的printk,只是把数据存到缓冲区里,  

241 //只有在这个函数调用后,才会在控制台打印出内容  

242 //该函数执行后可调用printk()函数将log_buf中符合打印级别要求的系统信息打印到控制台上。  

243 console_init(); 

244 

245 if (panic_later) 

246 panic(panic_later, panic_param);  

247 

248 //如果定义了CONFIG_LOCKDEP宏,那么就打印锁依赖信息,否则什么也不做  

249 lockdep_info(); 

250 

251 /*

252 * Need to run this when irqs are enabled, because it wants

253 * to self-test [hard/soft]-irqs on/off lock inversion bugs

254 * too:

255 */ 

256 //如果定义CONFIG_DEBUG_LOCKING_API_SELFTESTS宏  

257 //则locking_selftest()是一个空函数,否则执行锁自测  

258  locking_selftest(); 

259 

260 #ifdef CONFIG_BLK_DEV_INITRD  

261 if (initrd_start && !initrd_below_start_ok && 

262    page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) { 

263 printk(KERN_CRIT 'initrd overwritten (0x%08lx < 0x%08lx) - ' 

264    'disabling it./n', 

265    page_to_pfn(virt_to_page((void *)initrd_start)), 

266    min_low_pfn); 

267 initrd_start = 0; 

268 } 

269 #endif

270 

271  /* 虚拟文件系统的初始化 */

272  vfs_caches_init_early();       

273  cpuset_init_early();

274  mem_init();

275 

276 /* slab初始化 */

277 kmem_cache_init();  

278 

279 //是否是对SMP的支持,单核是否需要??这个要分析  

280 setup_per_cpu_pageset(); 

281 

282 numa_policy_init(); 

283 

284 if (late_time_init) 

285    late_time_init(); 

286 

287 //calibrate_delay()函数可以计算出cpu在一秒钟内执行了多少次一个极短的循环,  

288 //计算出来的值经过处理后得到BogoMIPS 值,  

289 //Bogo是Bogus(伪)的意思,MIPS是millions of instructions per second(百万条指令每秒)的缩写。  

290 //这样我们就知道了其实这个函数是linux内核中一个cpu性能测试函数。  

291 //http://blogold.chinaunix.net/u2/86768/showart_2196664.html  

292 calibrate_delay();

293    

294 //PID是process id的缩写  

295 //http://blog.csdn.net/satanwxd/archive/2010/03/27/5422053.aspx  

296 pidmap_init();

297 

298  /* 接下来的函数中,大多数都是为有关的管理机制建立专用的slab缓存 */ 

299 pgtable_cache_init();

300  

301 /* 初始化优先级树index_bits_to_maxindex数组 */

302 prio_tree_init();          

303 

304 //来自mm/rmap.c  

305 //分配一个anon_vma_cachep作为anon_vma的slab缓存。  

306 //这个技术是PFRA(页框回收算法)技术中的组成部分。  

307 //这个技术为定位而生——快速的定位指向同一页框的所有页表项。  

308 anon_vma_init();

309 

310 #ifdef CONFIG_X86  

311 if (efi_enabled) 

312 efi_enter_virtual_mode(); 

313 #endif 

314 

315 //根据物理内存大小计算允许创建进程的数量  

316 //http://www.jollen.org/blog/2006/11/jollen_linux_3_fork_init.html  

317 fork_init(totalram_pages);

318 

319 //给进程的各种资源管理结构分配了相应的对象缓存区  

320 //http://www.shangshuwu.cn/index.php/Linux内核的进程创建  

321 proc_caches_init(); 

322 

323 //创建 buffer_head SLAB 缓存  

324 buffer_init(); 

325 

326 unnamed_dev_init();

327 

328 //初始化key的management stuff  

329 key_init(); 

330 

331 //关于系统安全的初始化,主要是访问控制  

332 //http://blog.csdn.net/nhczp/archive/2008/04/29/2341194.aspx  

333 security_init();  

334 

335 //调用kmem_cache_create()函数来为VFS创建各种SLAB分配器缓存  

336 //包括:names_cachep、filp_cachep、dquot_cachep和bh_cachep等四个SLAB分配器缓存  

337 vfs_caches_init(totalram_pages); 

338  

339 radix_tree_init(); 

340 

341 //创建信号队列  

342 signals_init();

343 

344 /* rootfs populating might need page-writeback */ 

345 //回写相关的初始化  

346 //http://blog.csdn.net/yangp01/archive/2010/04/06/5454822.aspx 

347 page_writeback_init();   

348 

349 #ifdef CONFIG_PROC_FS  

350    proc_root_init(); 

351 #endif  

352 

353 //http://blogold.chinaunix.net/u1/51562/showart_1777937.html  

354 cpuset_init();

355  

356 ////进程状态初始化,实际上就是分配了一个存储线程状态的高速缓存  

357 taskstats_init_early(); 

358 

359 delayacct_init();  

360 

361 //测试CPU的各种缺陷,记录检测到的缺陷,以便于内核的其他部分以后可以使用他们工作。  

362 check_bugs(); 

363  

364 //电源相关的初始化  

365 //http://blogold.chinaunix.net/u/548/showart.php?id=377952  

366 acpi_early_init(); /* before LAPIC and SMP init */ 

367 

368 //接着进入rest_init()创建init进程,创建根文件系统,启动应用程序

369 rest_init(); 

370 }


2、start_kernel调用层次。简略的写出start_kernel函数的调用层次后面一步步分析它。其实可以概括为读取uboot传入的tag参数并且处理它们。


假设uboot传入的命令行参数为bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0。


a、其中setup_arch、setup_command_line 、do_early_para、unknown_bootoption这几个函数可以概括为处理uboot传入的tag参数。主要处理ATAG_MEM参数、ATAG_CMDLINE参数部分参数


b、console_init根据处理后的console=ttySAC0命令行参数选择合适的控制台


c、其中rest_init是start_kernel调用的最后一个函数主要用来根据 处理后的root=/dev/mtdblock3、init=/linuxrc命令后参数分别挂接合适的根文件系统与第一个init进程的启动。


start_kernel

    setup_arch                  //解析UBOOT传入的启动参数

    setup_command_line //解析UBOOT传入的启动参数

    do_early_param         //解析early参数,uboot中没传这个参数

    unknown_bootoption//解析到了命令行参数,saved_root_name在这块初始化

    console_init();//控制台初始化

    rest_init

        kernel_thread

            kernel_init

                prepare_namespace   //解析命令行参数解析成功挂接在哪个分区

                    mount_root//挂接根文件系统

                init_post

                    //执行应用程序

[1] [2]
关键字:Linux移植  start_kernel函数 引用地址:Linux移植之内核启动过程start_kernel函数简析

上一篇:Linux移植之tag参数列表解析过程分析
下一篇:Linux移植之内核启动过程引导阶段分析

推荐阅读最新更新时间:2024-11-06 01:16

linux 2.6.24.4在S3C2410上的移植(CS8900网卡驱动)(基于GEC2410)
SMDK2410配置默认使用的是DM9000A的网卡,因此我们需要修改成CS8900A的网卡驱动. 网上找到移植方法有两种方法,一种是将以前版本的cs8900.c驱动拿过来用,只要在配置中增加ARM_CS8900选项,这个代码网上有很多,拿过来试了以下,的确没问题. 另一种方法是修改2.6.24.4自带的cs89x0.c驱动,这个驱动没有2410的直接支持,我们需要修改. 这里采用第二种方法.参考了网上很多方法,将我的步骤整理如下,如有错误,欢迎指正. 1.内核配置菜单 由于cs89x0驱动依赖于NET_PCI,见drivers/net/Kconfig depends on NET_PCI && (ISA || M
[单片机]
<font color='red'>linux</font> 2.6.24.4在S3C2410上的<font color='red'>移植</font>(CS8900网卡驱动)(基于GEC2410)
linux 2.6.24.4及根文件系统在S3C2410上的移植(使用4.3.2编译器支持eabi)(基于GEC2410)
之前移植了linux-2.6.24.4和根文件系统(使用busybox-1.10.1创建)在GEC2410平台上运行。可参考之前的笔记: 内核配置: http://blog.csdn.net/shevsten/archive/2010/05/17/5599790.aspx 根文件系统: http://blog.csdn.net/shevsten/archive/2010/05/26/5625133.aspx 在测试一个用4.3(支持EABI)编译的应用程序时开始出现找不到库,将4.3.2编译器目录/usr/local/arm/compiler/arm-none-linux-gnueabi/libc/armv4t/lib中所
[单片机]
linux驱动移植的数据结构
对于嵌入式 Linux 系统来说,有各种体系结构的处理器和硬件平台,并且用户需要根据需求自己定制硬件板。只要是硬件平台有些变化,即使非常小,可能也需要做一些移植工作。内核移植是嵌入式Linux系统中最常见的一项工作。 内核移植工作主要是修改跟硬件平台相关的代码,一般不涉及 Linux 内核通用的程序。移植的难度也取决于两种硬件平台的差异。Linux 对于特定的硬件平台的软件就叫作 BSP(Board Support Package)。 由于 Linux 内核具备可移植性的特点,并且已经支持了各种体系结构的很多种目标板,我们很容易从中找到跟自己硬件类似的目标板。参考内核已经支持的目标板来移植 BSP,就如同使用模板开发程序。 因此
[单片机]
Linux 蓝牙系列 -- ARM-Linux蓝牙工具的移植
一 内核修改 ------------------------------------------------------------ 将内核的蓝牙做成模块形式。 并配置如下, Bluetooth subsystem support --- L2CAP protocol support SCO links support RFCOMM protocol support RFCOMM TTY support BNEP protocol support HIDP protocol support (NEW) Bluetooth d
[单片机]
ARM在嵌入式linux内核裁剪与移植的应用
微处理器用一片或少数几片大规模集成电路组成的中央处理器。这些电路执行控制部件和算术逻辑部件的功能。微处理器与传统的中央处理器相比,具有体积小,重量轻和容易模块化等优点。微处理器的基本组成部分有:寄存器堆、运算器、时序控制电路,以及数据和地址总线。微处理器能完成取指令、执行指令,以及与外界存储器和逻辑部件交换信息等操作,是微型计算机的运算控制部分。它可与存储器和外围电路芯片组成微型计算机。但这些专用操作系统都是商业化产品,其高昂的价格使许多低端产品的小公司望而却步;而且,源代码封闭性也大大限制了开发者的积极性。而Linux的开放性,使得许多人都认为Linux非常适合多数Intemet设备。Linux操作系统可以支持不同的设备和不同的
[单片机]
linux 2.6.32 在arm9(s3c2440)平台的移植
板子用的友善的mini2440, 起初按照光盘提供的手册, 照猫画虎,,,,,,,,,但是遇到各种问题, 很多未解决.....原因是还没理解每层目录的Makefile和Kconfig的关系, 以及在Kernel Configure菜单树中对应的选项, 以及对nand_flash设备的结构体的意义没搞清楚,~ so~ 在http://www.kernel.org/ 下载2.6.32的源代码. 编译器用的arm-linux-gcc 4.1.2 . 1 内核代码/uboot代码中中机器码的定义位置,在/root/linux-2.6.32/arch/arm/tools/mach-types 和 uboot/include/asm-
[单片机]
ARM-Linux驱动移植--DM9000网卡驱动移植
硬件平台:FL2440 内核版本:2.6.39 主机平台:Ubuntu 11.04 内核版本:2.6.35 交叉编译器:arm-linux-gcc 4.3.2 原创作品,转载请标明出处 http://blog.csdn.net/yming0221/article/details/6641579 1、DM9000网卡驱动的分析请见 http://blog.csdn.net/yming0221/article/details/6609742 2、如果想自己调试DM9000网卡驱动,那么在编译内核之前将网卡驱动不要编译进内核,启动后自己编译并加载内核 由于一般的驱动或者程序是通过NFS挂载到开发板上的,所以,如果没有网卡
[单片机]
U-Boot在基于ADSP BF533的嵌入式Linux系统上的移植
1 引言 Boot Loader(内核引导程序)是在操作系统内核运行之前运行的一段自举程序,用于初始化硬件设备、改变处理器运行模式、重组中断向量和建立内存空间映射图,从而将系统的软硬件带到一个合适的状态或者用户定制的特定状态,以便为最终加载操作系统内核准备好正确的环境 。 嵌入式Linux系统常用的Boot Loader有arm-boot、redboot、U-Boot等。U-Boot (全称Universal Boot Loader)是当前比较流行的遵循GPL条件的开放源码项目。U-Boot具有源码公开的特点,开发人员可根据自身需要进行裁减;支持多种处理器和嵌入式操作系统内核;具有多种设备驱动源码:支持种引导方式;具有功能强大
[应用]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved