Linux驱动程序开发.ppt
《Linux驱动程序开发.ppt》由会员分享,可在线阅读,更多相关《Linux驱动程序开发.ppt(112页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1Linux驱动程序移植及分析程杰程杰http:/2Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.2一、Linux内核启动过程概述二、MTD简介及修改NandMTD分区三、移植YAFFS文件系统四、Framebuffer驱动分析五、嵌入式Linux音频驱动程序设计六、LinuxIIS音频应用程序开发简介3一、Linux内核启动过程概述4Copyright2009ProchipElectronicsCo,ltd.AllRig
2、htsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.41Linux内核启动内核启动汇编代码部分检测内核是否支持处理器和开发板连接内核使用的虚拟地址,设置页表,使能MMU常规工作:复制数据段、调用strat_kernel函数C代码部分内核初始化调用rest_init函数,创建系统第一个进程init重设页表、设置系统时钟、初始化串口5Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutprio
3、rwrittenconsent.5开始确定内核是否支持架构_lookup_processor_type确定内核是否支持开发板_lookup_machine_type建立一级页表_creat_page_tables禁止IcacheDcache_arm720t_setup使能MMU_enale_mmu复制数据段清楚BSS段保存CPUID调用start_kernel汇编阶段6Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.6输出L
4、inux版本信息printk设置与体系相关的内容setup_arch初始化控制台console_init启动init过程rest_initC阶段7Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.72引导阶段代码分析引导阶段代码分析78ENTRY(stext)79msrcpsr_c,#PSR_F_BIT|PSR_I_BIT|MODE_SVCensuresvcmode80andirqsdisabled81mrcp15,0,r9,
5、c0,c0getprocessorid82bl_lookup_processor_typer5=procinfor9=cpuid83movsr10,r5invalidprocessor(r5=0)?84beq_error_pyes,errorp85bl_lookup_machine_typer5=machinfo86movsr8,r5invalidmachine(r5=0)?87beq_error_ayes,errora88bl_create_page_tables8Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottober
6、eproducedbyanymeanswithoutpriorwrittenconsent.879通过设置CPSR寄存器来确保处理器进入SVC模式,并禁止中断81读取协处理器CP15的寄存器C0获得CPUID82调用函数确定是否支持CPU85调用函数确定是否支持当前开发板如果_lookup_processor_type和_lookup_machine_type返回成功,系统将调用_creat_page_tables来创建一级页表以建立虚拟地址到物理地址的映射关系,接着会调用_enable_mmu来打开MMU9Copyright2009ProchipElectronicsCo,ltd.AllRi
7、ghtsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.93start_kernel函数分析函数分析进入start_kernel后,如果在串口中看不到信息,说明启动出现问题,可能原因有两个:bootloader传入参数不对setup_arch针对开发板的设置不正确在执行console_init函数前,系统信息保存在缓冲区中,只有在初始化控制台后才会输出10Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymean
8、swithoutpriorwrittenconsent.10(1)setup_arch函数分析函数分析arch/arm/kernel/void_initsetup_arch(char*cmdline_p)setup_processor();mdesc=setup_machine(machine_arch_type);if(mdesc-boot_params)tags=phys_to_virt(mdesc-boot_params);if(tags-=ATAG_CORE)if(!=0)squash_mem_tags(tags);parse_tags(tags);memcpy(saved_comma
9、nd_line,from,COMMAND_LINE_SIZE);saved_command_lineCOMMAND_LINE_SIZE-1=0;parse_cmdline(cmdline_p,from);paging_init(&meminfo,mdesc);11Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.11setup_processor()用来进行处理器相关的一些设置。setup_machine()用来获得开发板的m
10、achine_desc结构if(mdesc-boot_params)用来确定u-boot传入参数的启动地址之后的每一个tag,在中都定义了相应的处理函数eg内存tag:parse_tag_mem32()命令行tag:parse_tag_cmdline()parse_cmdline()对一些参数进行先期处理12Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.12“mem=”用来限制Linux使用的内存总量系统将调用early_
11、mem对其进行处理“console=”用来指定要使用的控制台名称、序号、参数console_setup函数将处理这个信息,并保存在全局结构console_cmdline中,后面console_init函数初始化控制台时会根据这些信息选择13Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.13(2)paging_init函数分析函数分析调用形式:paging_init(&meminfo,mdesc);其中:meminfo中存放
12、内存信息mdesc是开发板定义参数结构体调用流程:paging_init-devicemapes_init-map_io()14Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.14(3)console_init函数分析函数分析位置drivers/char/void_initconsole_init(void)initcall_t*call;/*SetupthedefaultTTYlinediscipline.*/(void)
13、tty_register_ldisc(N_TTY,&tty_ldisc_N_TTY);#ifdefCONFIG_EARLY_PRINTKdisable_early_printk();#endifcall=_con_initcall_start;while(callsetup_arch-setup_processorsetup_machinepage_tagsparse_cmdlinepaging_init-devicemaps_init-mdesc-map_io()console_init-register_console()16二、MTD简介及修改NandMTD分区17Copyright20
14、09ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.171MTD简介简介MTD(memorytechnologydevice内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。MTD的主要目的是为了使新的memory设备的驱动更加简单,为此它在硬件和上层之间提供了一个抽象的接口。MTD的所有源代码在/drivers/mtd子目录下。CFI接口的MTD设备分为四层,从上到下依次是:设备节点、MTD设备层、MTD原始设备层
15、和硬件驱动层。18Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.181.1Flash硬件驱动层硬件驱动层硬件驱动层负责在init时驱动Flash硬件,LinuxMTD设备的NORFlash芯片驱动遵循CFI接口标准,其驱动程序位于drivers/mtd/chips子目录下。NAND型Flash的驱动程序则位于/drivers/mtd/nand子目录下19Copyright2009ProchipElectronicsCo,l
16、td.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.191.2MTD原始设备原始设备原始设备层有两部分组成,一部分是MTD原始设备的通用代码,另一部分是各个特定的Flash的数据,例如分区。用于描述MTD原始设备的数据结构是mtd_info,这其中定义了大量的关于MTD的数据和操作函数。mtd_table()则是所有MTD原始设备的列表mtd_part()是用于表示MTD原始设备分区的结构,其中包含了mtd_info,因为每一个分区都是被看成一个MTD原始设备加在mtd_table中的20Copy
17、right2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.201.3MTD设备层设备层基于MTD原始设备,linux系统可以定义出MTD的块设备(主设备号31)和字符设备(设备号90)。MTD字符设备的定义在中实现,通过注册一系列fileoperation函数(lseek、open、close、read、write)。MTD块设备则是定义了一个描述MTD块设备的结构mtdblk_dev,并声明了一个名为mtdblks的指针数组,这数组中的每一
18、个mtdblk_dev和mtd_table中的每一个mtd_info一一对应。21Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.21文件系统文件系统在Bootloader中将JFFS(或JFFS2)的文件系统映像(或)烧到flash的某一个分区中,在/arch/arm/mach-your/文件的your_fixup函数中将该分区作为根文件系统挂载。文件系统:内核启动后,通过mount命令可以将flash中的其余分区作为文件
19、系统挂载到mountpoint上。22Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.222修改修改NandMTD分区分区SEP4020NandFlash有64MB空间目前分区情况:mtdblock00 x00000000-0 x01000001Mmtdblock10 x00100000-0 x06000005Mmtdblock20 x00600000-0 x1E0000024Mmtdblock30 x01E00000-0
20、x0400000034M23Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.23SEP4020NAND的驱动程序,其目录位于:宏定义:#defineNUM_PARTITIONS4/NAND的分区数目(这里分为4个分区)#defineUBOOT_SIZESZ_1M*1/UBOOT分区空间大小#defineKERNEL_SIZESZ_1M*5/内核分区空间大小#defineROOT_SIZESZ_1M*24/根文件系统分区大小#
21、defineUSER_SIZESZ_1M*34/用户空间分区大小24Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.24staticstructmtd_partitionpartition_info=.name=U-boot,.offset=0,.size=UBOOT_SIZE,.name=linux2.6.16kernel,.offset=UBOOT_SIZE,.size=KERNEL_SIZE,.name=root,.o
22、ffset=UBOOT_SIZE+KERNEL_SIZE,.size=ROOT_SIZE,.name=user,.offset=UBOOT_SIZE+KERNEL_SIZE+ROOT_SIZE,.size=USER_SIZE;25Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.25上面的代码可以看出:NAND被分为4个分区我们可能修改NAND分区数目和各分区的大小(包括增加分区删除分区合并分区等)注意:无论做任何修改,所有分
23、区的大小不能超过NAND的总量(目前64M).26Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.26增加一个分区增加一个分区#defineNUM_PARTITIONS5/NAND的分区数目(修改)#defineUBOOT_SIZESZ_1M*1/UBOOT分区空间大小#defineKERNEL_SIZESZ_1M*5/内核分区空间大小#defineROOT_SIZESZ_1M*24/根文件系统分区大小#defineUSER
24、_SIZESZ_1M*17/用户空间分区大小(修改)#defineUSER1_SIZESZ_1M*17/用户增加的分区(修改)27Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.27这样就将原来的第四分区(34M)分为两个分区(17M+17M)的空间.在串口调试工具输出的NAND分区信息中可以看到如下五个分区:Creating5MTDpartitionsonNAND64MiB3,3V8-bit:0 x00000000-0 x
25、00100000:U-boot0 x00100000-0 x00600000:linux2.6.16kernel0 x00600000-0 x01e00000:root0 x01e00000-0 x02f00000:user0 x02f00000-0 x04000000:user128Copyright2009ProchipElectronicsCo,ltd.AllRightsReserved.Nottobereproducedbyanymeanswithoutpriorwrittenconsent.28删除删除(合并合并)一个分区一个分区#defineNUM_PARTITIONS3/NAND
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 驱动程序 开发
限制150内