Chinaunix首页 | 论坛 | 博客
  • 博客访问: 151801
  • 博文数量: 40
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 908
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-03 11:03
个人简介

学习linux

文章分类
文章存档

2014年(7)

2013年(33)

我的朋友

分类: 嵌入式

2013-09-04 07:24:28

在移植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) |
给主人留下些什么吧!~~