微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > linux内核启动流程

linux内核启动流程

时间:11-22 来源:互联网 点击:

8 time_init()

这个函数用来做体系相关的timer的初始化,armnommu的在arch/armnommu/kernel/time.c。这里调用了
在 include/asm-armnommu/arch-xxxx/time.h中的inline函数setup_timer,setup_timer()函数
的设计与硬件设计紧密相关,主要是根据硬件设计情况设置时钟中断号和时钟频率等。

[cpp]view plaincopyprint?

  1. void__inline__setup_timer(void)
  2. {
  3. /*-----disabletimer-----*/
  4. CSR_WRITE(TCR0,xxx);
  5. CSR_WRITE(AIC_SCR7,xxx);/*settingpriorityleveltohigh*/
  6. /*timer0:100ticks/sec*/
  7. CSR_WRITE(TICR0,xxx);
  8. timer_irq.handler=xxxxxx_timer_interrupt;
  9. setup_arm_irq(IRQ_TIMER,&timer_irq);/*IRQ_TIMERistheinterruptnumber*/
  10. INT_ENABLE(IRQ_TIMER);
  11. /*Clearinterruptflag*/
  12. CSR_WRITE(TISR,xxx);
  13. /*enabletimer*/
  14. CSR_WRITE(TCR0,xxx);
  15. }


1.9 console_init()

控制台初始化。控制台也是一种驱动程序,由于其特殊性,提前到该处完成初始化,主要是为了提前看到输出
信息,据此判断内核运行情况。很多嵌入式Linux操作系统由于没有在/dev目录下正确配置console设备,造
成启动时发生诸如unable to open an initial console的错误。

/*******************************************************************************/
init_modules()函数到smp_init()函数之间的代码一般不需要作修改,
如果平台具有特殊性,也只需对相关函数进行必要修改。
这里简单注明了一下各个函数的功能,以便了解。
/*******************************************************************************/

1.10 init_modules()

模块初始化。如果编译内核时使能该选项,则内核支持模块化加载/卸载功能

1.11 kmem_cache_init()

内核Cache初始化。

1.12 sti()

使能中断,这里开始,中断系统开始正常工作。

1.13 calibrate_delay()

近似计算BogoMIPS数字的内核函数。作为第一次估算,calibrate_delay计算出在每一秒内执行多少次
__delay循环,也就是每个定时器滴答(timer tick)―百分之一秒内延时循环可以执行多少次。这种计算只
是一种估算,结果并不能精确到纳秒,但这个数字供内核使用已经足够精确了。
BogoMIPS的数字由内核计算并在系统初始化的时候打印。它近似的给出了每秒钟CPU可以执行一个短延迟循环
的次数。在内核中,这个结果主要用于需要等待非常短周期的设备驱动程序――例如,等待几微秒并查看设备的
某些信息是否已经可用。
计算一个定时器滴答内可以执行多少次循环需要在滴答开始时就开始计数,或者应该尽可能与它接近。全局变
量jiffies中存储了从内核开始保持跟踪时间开始到现在已经经过的定时器滴答数, jiffies保持异步更
新,在一个中断内——每秒一百次,内核暂时挂起正在处理的内容,更新变量,然后继续刚才的工作。

1.14 mem_init()

内存初始化。本函数通过内存碎片的重组等方法标记当前剩余内存, 设置内存上下界和页表项初始值。

1.15 kmem_cache_sizes_init()

内核内存管理器的初始化,也就是初始化cache和SLAB分配机制。

1.16 pgtable_cache_init()

页表cache初始化。

1.17 fork_init()

这里根据硬件的内存情况,如果计算出的max_threads数量太大,可以自行定义。

1.18 proc_caches_init();

为proc文件系统创建高速缓冲

1.19 vfs_caches_init(num_physpages);

为VFS创建SLAB高速缓冲

1.20 buffer_init(num_physpages);

初始化buffer

1.21 page_cache_init(num_physpages);

页缓冲初始化

1.22 signals_init();

创建信号队列高速缓冲

1.23 proc_root_init();

在内存中创建包括根结点在内的所有节点

1.24 check_bugs();

检查与处理器相关的bug

1.25 smp_init();


1.26 rest_init(); 此函数调用kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)函数。


1.26.1 kernel_thread()函数分析

这里调用了arch/armnommu/kernel/process.c中的函数kernel_thread,kernel_thread函数中通过
__syscall(clone) 创建新线程。__syscall(clone)函数参见armnommu/kernel目录下的entry- common.S文件。

1.26.2 init()完成下列功能:

Init()函数通过kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)的回调
函数执行,完成下列功能。
do_basic_setup()
在该函数里,sock_init()函数进行网络相关的初始化,占用相当多的内存,如果所开发系统不支持网络功
能,可以把该函数的执行注释掉。
do_initcalls()实现驱动的初始化, 这里需要与vmlinux.lds联系起来看才能明白其中奥妙。

[cpp]view plaincopyprint?

  1. staticvoid__initdo_init

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top