Kernel在启动时会调用定义的初始化接口对cpu及外部设备进行初始化.根据需要的初始化顺序定义类型,把初始化函数添加到初始化链表中.
Kernel的初始化函数添加在init.h中定义:
#define pure_initcall(fn) __define_initcall("0",fn,0)
#define core_initcall(fn) __define_initcall("1",fn,1)
#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
#define postcore_initcall(fn) __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
#define arch_initcall(fn) __define_initcall("3",fn,3)
#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
#define subsys_initcall(fn) __define_initcall("4",fn,4)
#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
#define fs_initcall(fn) __define_initcall("5",fn,5)
#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
#define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
#define late_initcall(fn) __define_initcall("7",fn,7)
#define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
比较常用的初始化函数为添加module_init对应的为device_initcall.
#define __initcall(fn) device_initcall(fn)
#define module_init(x) __initcall(x);
Kernel调用初始化列表流程:
start_kernel
->setup_arch
->mdesc.init_early
->am33xx_init_early
->rest_init
->kernel_init
->do_basic_setup
->do_initcalls
->各级初始化函数
在TI提供的linux软件平台代码中,kernel初始化主要包括以下步骤:
arch_initcall(customize_machine)
该函数为主板初始化函数,函数使用的machine_desc结构中存放了当前主板的相关信息和操作函数.
执行流程:
arch_initcall(customize_machine)
am335x_evm_init
{
am33xx_cpuidle_init
am33xx_mux_init
omap_serial_init
am335x_evm_i2c_init(EEPROM probe会进行外围接口的初始化)
omap_sdrc_init
usb_musb_init
clk_add_alias
}
module_init(at24_init)
am335x_evm_init中的am335x_evm_i2c_init会导致module_init注册的初始化函数at24_init被执行,在at24_init中,会根据EEPROM中存储的设备类型对设备外围设备进行初始化,执行流程如下:
at24_probe
chip.setup(am335x_evm_setup)
setup_general_purpose_evm
_configure_device
dev_cfg->device_init
am335x_rtc_init
clkout2_enable
enable_ecap0
lcdc_init
mfd_tscadc_init
rgmii1_init
rgmii2_init
usb0_init
usb1_init
evm_nand_init
i2c1_init
lis331dlh_init
mcasp1_init
mmc1_init
mmc2_wl12xx_init
mmc0_init
mmc0_no_cd_init
spi0_init
uart1_wl12xx_init
wl12xx_init
d_can_init
matrix_keypad_init
volume_keys_init
uart2_init
haptics_init
sgx_init
am33xx_init_early am33xx_init_early
omap2_set_globals_am33xx//初始化全局register地址
omap3xxx_check_revision//校验cpu版本
am33xx_check_features//check cpu features flag
omap_common_init_early//配置dma size
am33xx_voltagedomains_init//配置需要的电压控制
omap44xx_prminst_init//配置prm register base
am33xx_powerdomains_init// 配置 power domain register(gfx,rtc…)地址及操作函数
omap44xx_cminst_init//配置 clock register base
am33xx_clockdomains_init//配置clock domain regist地址及操作
am33xx_hwmod_init//配置支持的总线接口及接口相关信息
omap_hwmod_init_postsetup//配置hwmod的postsetup状态
omap3xxx_clk_init//配置cpu clock