嵌入式 Linux framebuffer 驱动移植日志

Linux 初始化过程:

/init/main.c中的start_kernel()开始:
该函数中,主要做了下列事情:

1)先是
boot_cpu_init();
初始化了启动相关的内容后
然后
printk(KERN_NOTICE);
printk(linux_banner);
打印内核信息,比如我这里的:
Linux version 2.6.22.2 ([email protected]) (gcc version 4.3.2 (GCC) ) #89 Fri May 15 11:25:09 CST 2009

2
其后主要初始化了中断,时钟等:
init_IRQ();
init_timers();
softirq_init();
3
再打印出命令行:
printk(KERN_NOTICE "Kernel command line: %s/n", boot_command_line);
如此处的:
Kernel command line: root=/dev/mtdblock2 rw init=/linuxrc console=ttyS0,115200 mem=64M rootfstype=jffs2

4
后来才是调用
console_init();
去初始化Uart的,就是调用uartprobe函数。

5
先预初始化:
cpuset_init_early();

6
初始化内存:
mem_init();

7
初始化buffer
buffer_init();
再初始化cpu(组):
cpuset_init();

8
check_bugs();
去测试CPU的相关情况:

CPU: Testing write buffer coherency: ok

9
最后调用:
rest_init();
去启动线程
kernel_init
{
。。。
do_basic_setup();
。。。
init_post();

}

其中调用
do_basic_setup();
{
。。。
driver_init();
。。。
do_initcalls();
。。。
}
去初始化Linux kernel相关的内容

其中
driver_init()
{
/* These are the core pieces */
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();
system_bus_init();
cpu_dev_init();
memory_dev_init();
attribute_container_init();
}
初始化真正的系统的

device
busclass等等内容,

然后的
do_initcalls()
{
//
__Start 开始 __End 结束,
//
以此调用之前内核中相关的__init前缀的那些初始化函数
}

其中,这些用__init标明的函数,可以在system.map中看到对应的信息,
包括对应的变量和其对应的地址

c001d164 t __initcall_ptrace_break_init1
c001d164 T __initcall_start
c001d168 t __initcall_consistent_init
1
c001d16c t __initcall_sysctl_init
1
c001d170 t __initcall_init_jiffies_clocksource
1
c001d174 t __initcall_pm_init
1
c001d178 t __initcall_ksysfs_init1
。。。。。。。。。。。。。。。
c001d194 t __initcall_sock_init1
c001d198 t __initcall_netlink_proto_init
1
c001d19c t __initcall_kobject_uevent_init
2
c001d1a0 t __initcall_amba_init
2
c001d1a4 t __initcall_tty_class_init
2
c001d1a8 t __initcall_vtconsole_class_init
2
c001d1ac t __initcall_customize_machine3
。。。。。。。。。。。
c001d1b0 t __initcall_clk_init3
c001d1b4 t __initcall_dma_init
3
c001d1bc t __initcall_topology_init
4
c001d1c0 t __initcall_param_sysfs_init4
。。。。。。。。。。。。。
c001d200 t __initcall_init_pipe_fs5
c001d204 t __initcall_eventpoll_init5
。。。。。。。。。。。。。。
c001d24c t __initcall_init6
c001d250 t __initcall_kallsyms_init
6
c001d254 t __initcall_utsname_sysctl_init
6
c001d258 t __initcall_init_per_zone_pages_min
6
c001d25c t __initcall_pdflush_init6
。。。。。。。。。。
c001d2e8 t __initcall_loop_init6
c001d2ec t __initcall_net_olddevs_init
6
c001d2f0 t __initcall_loopback_init
6
c001d2f4 t __initcall_init_mtd
6
c001d2f8 t __initcall_afs_parser_init
6
c001d2fc t __initcall_init_mtdchar
6
c001d300 t __initcall_init_mtdblock
6
c001d304 t __initcall_init_nftl6
。。。。。。。。。。。。
c001d388 t __initcall_ip_auto_config7
。。。。。。。。。。。

可以看出,这些函数经过系统处理后,
加了前缀__initcall_和后缀的数字,看起来是表示启动的阶段。
也就是加了和函数对应的一个个变量(标示)

当然,也可以找到函数对应的首地址,比如
变量
c001d1b0 t __initcall_clk_init3
对应的函数clk_init放在c000e624
c000e624 t clk_init

然后,调用
init_post()
{
1.
打开console
sys_open("/dev/console", O_RDWR, 0)

2.运行命令:
run_init_process(ramdisk_execute_command);

run_init_process(execute_command);

3.运行系统初始化文件:
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

}
最后,我们才进入我们熟悉的嵌入式Linux环境,

才能输入用户名和密码(如果有的话),比如:
Welcome to Embedded Linux
(none) login: root
Dec 31 17:00:11 login[704]: root login on 'ttyS0'
# cd /
。。。


【附录】
关于系统架构中,如何把函数和系统联系起来

注:我这里是arm架构的板子

arch/arm/kernel/setup.c
void __init setup_arch(char **cmdline_p)
{
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
}

mdesc即使machine description
对应的是你在arch/arm/mach-XXX/mach-XXXX.c
中定义的,类似于如下的内容:

MACHINE_START(XXXX, "XXXX")
/* Maintainer: Austriamicrosystems Ltd */
.phys_io = XXXX,
.io_pg_offst = XXXX,
.boot_params = XXXX,
.map_io   = XXXX_map_io,
.init_irq = XXXX_init_irq,
.timer   = &XXXX_timer,
.init_machine = XXXX_init,
MACHINE_END

其中XXX代表你的板子(架构)名字。

 

 

 

 

移植日志:

 

1)初始化LCD控制器

  Arch/arm/mach-s3c2410/Mach-smdk2410.c

 

static struct s3c2410fb_mach_info s3c2410fb_info _initdata = {

       .fixed_syncs     = 0,

    .regs    = {

           .lcdcon1    = S3C2410_LCDCON1_TFT16BPP |

                    S3C2410_LCDCON1_TFT |

                // S3C2410_LCDCON1_ENVID |

                    S3C2410_LCDCON1_CLKVAL(1),

           .lcdcon2    = S3C2410_LCDCON2_VBPD(25) | S3C2410_LCDCON2_VFPD(5)

| S3C2410_LCDCON2_VSPW(1),

     .lcdcon3    = S3C2410_LCDCON3_HBPD(67) | S3C2410_LCDCON3_HFPD(40),

      .lcdcon4    = S3C2410_LCDCON4_HSPW(31) | S3C2410_LCDCON4_MVAL(13),

      .lcdcon5    = S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_HWSWP |

S3C2410_LCDCON5_PWREN|S3C2410_LCDCON5_INVVLINE|S3C2410_LCDCON5_INVV

FRAME ,

    },

   .lpcsel        = 0,// ((0xCE6) & ~7) | 1<<4,

   .gpccon=        0xaaaaaaaa,

   .gpccon_mask=   0xffffffff,

   .gpcup=         0xffffffff,

   .gpcup_mask=    0xffffffff,

   .gpdcon=        0xaaaaaaaa,

   .gpdup =       0xFFFFFFFF,

   .gpdup_mask=    0xffffffff,

   .width        = 640,

   .height       = 480,

   .yres        = {

       .min    = 480,

       .max    = 480,

       .defval    = 480,

    },

   .xres        = {

      .min    = 640,

      .max    = 640,

      .defval = 640,

   },

.bpp        = {

     .min    = 16,

     .max    = 16,

     .defval = 16,

   },

};

2)添加信息到设备

static void __init smdk2410_lcd_init(void)

{

       set_s3c2410fb_info(&s3c2410fb_info);  //devs.c中实现的加入控制器信息到device设备

}

 

  3)在系统初始化中增加对 lcd 的初始化

MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch

                                * to SMDK2410 */

       /* Maintainer: Jonas Dietsche */

       .phys_ram      = S3C2410_SDRAM_PA,

       .phys_io  = S3C2410_PA_UART,

       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

       .boot_params  = S3C2410_SDRAM_PA + 0x100,

       .map_io          = smdk2410_map_io,

       .init_irq   = smdk2410_init_irq,

       .timer             = &s3c24xx_timer,

       .init_machine =smdk2410_lcd_init;

MACHINE_END

4make menuconfig 中还要加入 S3C2410 frambuffer support 选项。

     Device Driver

           Ghipics support

            具体显示设备支持选项、Framebuffer终端配置选项和Framebuffer Logo配置选项

         s3c2410 LCD framebuffer support

          

  4)最后编译执行,就能看到小企鹅了。

你可能感兴趣的:(c,timer,linux,command,嵌入式)