在移植nand flash驱动之前先学习一下linux的驱动加载过程:(这是我看过的一个博客,但不记得在哪里了 :( )
1. bootloader跳转到内核的起始位置后,压缩过的kernel入口在arch/arm/boot/compressed/head.S,它将调用函数decompress_kernel()(arch/arm/boot/compressed/misc.c)解压,打印“Uncompressing Linux...”,调用gunzip(),打印"done, booting the kernel."
2. 然后call_kernel,执行解压后的kernel,最后调用start_kernel() (init/main.c)转入体系结构无关的通用C代码,在start_kernel()中完成了一系 列系统初始化,并启动了调度器;最后调用函数rest_init()将创建第一个核心线程kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND),调用kernel_init()函数。
3. kernel_init()中先调用kernel_init_freeable();再调用free_initmem();最后执行根文件系统的配置init。
if (!run_init_process("/sbin/init") ||
!run_init_process("/etc/init") ||
!run_init_process("/bin/init") ||
!run_init_process("/bin/sh"))
return 0;
4. 在上面的kernel_init_freeable()中,主要有三个函数。
do_basic_setup();
/* Open the /dev/console on the rootfs, this should never fail */
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
pr_err("Warning: unable to open an initial console.\n");
load_default_modules();
5.
static void __init do_basic_setup(void)
{
cpuset_init_smp();
usermodehelper_init();
shmem_init();
driver_init();
init_irq_proc();
do_ctors();
usermodehelper_enable();
do_initcalls();
}
6.
/*
* This function requests modules which should be loaded by default and is
* called twice right after initrd is mounted and right before init is
* exec'd. If such modules are on either initrd or rootfs, they will be
* loaded before control is passed to userland.
*/
void __init load_default_modules(void)
{
load_default_elevator_module();
}
在include/linux/elevator.h中,什么也没有做:
static inline void load_default_elevator_module(void) { }
7. driver_init()在drivers/base/init.c,主要实现了/sys的设备模型,还有platform初始化:
/**
* driver_init - initialize driver model.
*
* Call the driver model init functions to initialize their
* subsystems. Called early from init/main.c.
*/
void __init driver_init(void)
{
/* These are the core pieces */
devtmpfs_init();
devices_init();
buses_init();
classes_init();
firmware_init();
hypervisor_init();
/* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init();
cpu_dev_init();
memory_dev_init();
}
8. do_initcalls()在init/main.c中,加载8个优先级函数,这些函数主要是一些驱动核心,模块,有一定顺序的代码:
static void __init do_initcalls(void)
{
int level;
for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level);
}
static initcall_t *initcall_levels[] __initdata =
{
__initcall0_start,
__initcall1_start,
__initcall2_start,
__initcall3_start,
__initcall4_start,
__initcall5_start,
__initcall6_start,
__initcall7_start,
__initcall_end,
};
阅读(4237) | 评论(0) | 转发(0) |