ARM嵌入式Linux系统开发详解
文章平均质量分 61
Linuxdianc
这个作者很懒,什么都没留下…
展开
-
25.4 小 结
25.4 小 结本章讲解了Linux内核USB驱动体系结构、USB设备驱动结构等知识,并在最后给出了两个USB设备驱动开发实例。USB是目前流行的总线接口之一,物理接口简单,但是协议和操作非常复杂。读者在学习USB设备驱动开发的过程中,掌握好USB的体系结构,会得到事半功倍的效果。原创 2009-12-18 09:23:00 · 535 阅读 · 0 评论 -
20.4 建立目标平台代码框架
20.4 建立目标平台代码框架在20.3.3节编译的内核代码最后出现了链接错误,提示vmlinux.lds文件链接失败。lds文件是GNU ld工具使用的一种脚本文件,该文件描述了如何分配链接后的内存区域和地址等信息,通过lds文件报的错误可以推理分析问题产生的原因。20.4.1 ARM处理器相关结构首先打开arch/arm/kernel/vmlinux.lds文件,找到815行,原创 2009-12-18 08:46:00 · 711 阅读 · 0 评论 -
20.3.3 测试工程框架
20.3.3 测试工程框架工程框架配置修改完毕后,需要进行简单的测试,根据测试结果判断框架是否搭建成功。回到内核代码顶层目录,输入make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig命令,出现内核设置图形界面。在内核配置界面选择Load an Alternate Configuration File菜单,进入后输入“arch/arm/ con原创 2009-12-18 08:44:00 · 678 阅读 · 0 评论 -
20.3.2 设置宏与代码文件的对应关系
20.3.2 设置宏与代码文件的对应关系在设置宏与代码文件对应关系之前,首先建立一个空的代码文件。在arch/arm/mach-s3c 2410目录下建立mach-mini2440.c文件,用于存放与mini2440开发板相关的代码。建立mach-mini2440.c文件后,修改arch/arm/mach-s3c2410/Makefile文件,在文件最后加入mach-mini2440.c原创 2009-12-18 08:44:00 · 554 阅读 · 0 评论 -
20.3.1 加入编译菜单项
20.3.1 加入编译菜单项修改arch/arm/mach-s3c2410/Kconfig文件,在endmenu之前加入下面的内容: 87 config ARCH_MINI2440 // 开发板名称宏定义88 bool "mini2440" // 开发板名称89 select CPU_S3C2440 // 开发板使用的处理器类型原创 2009-12-18 08:43:00 · 464 阅读 · 0 评论 -
20.3 建立目标平台工程框架
20.3 建立目标平台工程框架Linux内核2.6版本已经对ARM处理器有很好的支持,并且对三星公司的S3C2440提供一定支持。但是,嵌入式硬件系统的差别很大,移植Linux内核到新的开发板仍然需要修改或者增加针对特定硬件的代码。Linux内核使用了复杂的工程文件结构,向内核添加新的代码文件需要让内核工程文件知道才行。对于ARM处理器来说,相关的文件都存放在arch/arm目录下:原创 2009-12-18 08:42:00 · 555 阅读 · 0 评论 -
20.2 平台相关代码结构
20.2 平台相关代码结构移植Linux是一项复杂的工作,不仅对目标硬件平台的资源要充分了解,还需要了解Linux内核代码,尤其是与体系结构有关的部分。本节从内核的平台相关代码入手,先介绍内核的工作原理,然后讲解如何移植一个普通的Linux内核到S3C2440A为目标平台的开发板。在第15章介绍过Linux内核代码结构,与平台相关的代码主要存放在arch目录下,对应的头文件在includ原创 2009-12-18 08:40:00 · 607 阅读 · 0 评论 -
20.1 Linux内核移植要点
20.1 Linux内核移植要点Linux的代码完全开放以及其良好的结构设计非常适于嵌入式系统。移植Linux系统包括内核、程序库和应用程序,其中最主要的就是内核移植。由于Linux内核的开放性,出现了许多针对嵌入式硬件系统的内核版本,其中著名的包括μcLinux、RT-Linux等。Linux本身对内存管理(MMU)有很好的支持。因此,在移植的时候首先要考虑到目标硬件平台是否支持MMU原创 2009-12-18 08:39:00 · 990 阅读 · 0 评论 -
第20章 Linux内核移植
第20章 Linux内核移植软件移植的概念简单地说就是让一套软件在指定的硬件平台上正常运行。移植至少包括了两个不同的硬件或者软件平台。对于应用软件来说,移植主要考虑操作系统的差异,重点在修改系统调用。本章的重点是Linux内核移植,需要考虑硬件平台的差异,涉及较多知识。主要内容如下:q Linux内核移植要点;q 内核体系结构框架;q 从现有代码移植原创 2009-12-18 08:35:00 · 746 阅读 · 0 评论 -
14.4 移植U-Boot到开发板
14.4 移植U-Boot到开发板U-Boot虽然支持众多处理器和开发板,但是嵌入式系统的硬件是千差万别的,在使用U-Boot的时候,仍然需要针对自己的开发板做适当的修改。幸好U-Boot是一个结构设计合理的软件,在移植过程中严格按照U-Boot的工程结构移植很容易就能取得成功。本节将介绍如何移植U-Boot程序到ARM开发板。14.4.1 U-Boot移植的一般步骤从14.2节对原创 2009-12-17 17:10:00 · 1107 阅读 · 0 评论 -
20.5 构建目标板代码
20.5 构建目标板代码Linux内核已经为ARM处理器设计好了代码框架,只要按照这个框架加入针对某种开发板和处理器的代码即可工作。加入代码还是按照前面提到的原则,能使用已有的通用代码尽量使用,并且尽可能地参考现有开发板代码的处理方法。20.5.1 处理器初始化首先在mach-mini2440.c文件中加入处理器初始化代码如下: 56 void __init mini244原创 2009-12-18 08:48:00 · 559 阅读 · 0 评论 -
20.6 小 结
20.6 小 结本章介绍了如何移植Linux内核代码到新的开发板。移植内核到新的硬件平台是一件繁琐的事情,读者在移植过程中需要有耐心。移植内核代码要涉及软件和硬件相关的知识,读者应该结合硬件提供的电路图纸和手册,利用现有的软件工具和代码,构建符合需求的内核代码。第21章将讲解Linux内核和应用程序的调试技术。原创 2009-12-18 08:51:00 · 583 阅读 · 0 评论 -
第25章 USB驱动开发
第25章 USB驱动开发USB是目前最流行的系统总线之一。随着计算机周围硬件的不断扩展,各种设备使用不同的总线接口,导致计算机外部总线种类繁多,管理困难,USB总线正是因此而诞生的。USB总线提供了所有外部设备的统一连接方式,并且支持热插拔,方便了厂商开发设备和用户使用设备。本章将详细介绍USB相关的知识,主要内容如下:q USB总线体系结构介绍;q USB体系工原创 2009-12-18 08:58:00 · 655 阅读 · 0 评论 -
25.3.2 USB键盘驱动
25.3.2 USB键盘驱动USB键盘驱动与串口驱动结构类似,不同的是,使用USB设备核心提供的usb_keyboard_driver结构作为设备核心结构。下面讲解USB键盘驱动的重点部分。1.驱动初始和注销USB键盘驱动初始化和注销函数定义如下: static int _ _init usb_kbd_init(void){ int result = usb_reg原创 2009-12-18 09:21:00 · 1106 阅读 · 0 评论 -
25.3.1 USB串口驱动
25.3.1 USB串口驱动USB串口驱动关键是向内核注册串口设备结构,并且设置串口的操作。下面是一个典型的USB设备驱动分析。1.驱动初始化函数usb_serial_init()函数是一个典型的USB设备驱动初始化函数,定义如下: static int __init usb_serial_init(void){ int i; int result;原创 2009-12-18 09:20:00 · 1147 阅读 · 0 评论 -
25.3 USB驱动实例剖析
25.3 USB驱动实例剖析USB体系支持多种类型的设备。在Linux内核,所有的USB设备都使用usb_driver结构描述。对于不同类型的USB设备,内核使用传统的设备驱动模型建立设备驱动描述,然后映射到USB设备驱动,最终完成特定类型的USB设备驱动。原创 2009-12-18 09:20:00 · 725 阅读 · 0 评论 -
25.2.4 USB驱动程序框架
25.2.4 USB驱动程序框架Linux内核代码driver/usb/usb-skeleton.c文件是一个标准的USB设备驱动程序。编写一个USB设备的驱动可以参考usb-skeleton.c文件,实际上,可以直接修改该文件驱动新的USB设备。下面以usb-skeleton.c文件为例分析usb-skel设备驱动框架。1.基本数据结构usb-skel设备使用自定义结构usb_sk原创 2009-12-18 09:18:00 · 668 阅读 · 0 评论 -
25.2.3 设备驱动结构
25.2.3 设备驱动结构USB协议规定了许多种USB设备类型。Linux内核实现了音频设备、通信设备、人机接口、存储设备、电源设备、打印设备等几种USB设备类。1.基本概念Linux内核实现的USB设备类驱动都是针对通用的设备类型设计的。如存储设备类,只要USB存储设备是按照标准的USB存储设备规范实现的,就可以直接被内核USB存储设备驱动程序驱动。如果一个USB设备是非标准的,则原创 2009-12-18 09:17:00 · 658 阅读 · 0 评论 -
25.2.2 主机驱动结构
25.2.2 主机驱动结构USB主机控制器有3种类型:q OHCI:英文全称是Open Host Controller Interface,是用于SiS和Ali芯片组的USB控制器。q UHCI:英文全称是Universal Host Controller Interface,用于Intel和AMD芯片组的USB控制器。UHCI类型的控制器比OHCI控制器硬件结构原创 2009-12-18 09:15:00 · 748 阅读 · 0 评论 -
25.2.1 Linux内核USB驱动框架
25.2.1 Linux内核USB驱动框架图25-2是Linux内核从主机和设备两个角度观察USB总线结构的示意图。从图25-2中可以看出,Linux内核USB驱动是按照主机驱动和设备驱动两套体系实现的,下面介绍两套体系的结构和特点。1.基本结构图25-2的左侧是主机驱动结构。主机驱动的最底层是USB主机控制器,提供了OHCI/EHCI/UHCI这3种类型的总线控制功能。在USB原创 2009-12-18 09:12:00 · 1448 阅读 · 0 评论 -
25.2 USB驱动程序框架
25.2 USB驱动程序框架Linux内核提供了完整的USB驱动程序框架。USB总线采用树形结构,在一条总线上只能有唯一的主机设备。Linux内核从主机和设备两个角度观察USB总线结构。本节介绍Linux内核USB驱动程序框架。原创 2009-12-18 09:10:00 · 698 阅读 · 0 评论 -
25.1 USB体系介绍
25.1 USB体系介绍USB(Universal Serial Bus)是一个总线协议标准,最初是由Intel、NEC、Compaq、DEC、IBM、Microsoft等公司联合制定的。到目前为止,USB共有1.0、1.1和2.0这3个标准,主要区别是传输速率不同,体系结构也有一些差别。25.1.1 USB设计目标USB的设计目标是对现有的PC体系进行扩充,但是目前不仅是PC,许原创 2009-12-18 09:06:00 · 738 阅读 · 0 评论 -
14.3.5 relocate标号
14.3.5 relocate标号relocate部分的代码负责把U-Boot Stage2的代码从Flash存储器加载到内存,代码 如下: 163 #ifndef CONFIG_SKIP_RELOCATE_UBOOT164 relocate: /* relocate U-Boot to RAM */165 adr r0, _start原创 2009-12-17 17:05:00 · 801 阅读 · 0 评论 -
14.2 U-Boot分析
14.2 U-Boot分析Bootloader代码是嵌入式系统复位后进入操作系统前执行的一段代码。通过Bootloader的代码初始化处理器的各寄存器以及其他外部设备,建立存储器映射图以及初始化堆栈,为操作系统提供基本的运行环境。由于嵌入式系统的硬件的多样性,不可能有通用的Bootloader,因此需要根据具体硬件特点移植。本节以目前应用比较广泛的U-Boot为例讲解嵌入式系统Bootloa原创 2009-12-17 16:38:00 · 1643 阅读 · 0 评论 -
8.2 多线程开发
8.2.1 线程的概念线程是一种轻量级的进程。与进程最大的不同是线程没有系统资源。线程是操作系统调度的最小单位,可以理解为一个进程是由一个或者多个线程组成的。在操作系统内核中,是按照线程作为调度单位来调度资源的。在一个进程内部,多个线程之间的资源是共享的。也就是说,如果一个进程内部的所有线程拥有相同的代码地址空间和数据空间,则任意一个线程都可以访问其他线程的数据。8.2.2 进程和线程原创 2009-12-17 15:28:00 · 581 阅读 · 0 评论 -
8.1.4 等待进程结束
8.1.4 等待进程结束子进程虽然是独立于父进程的,但是和父进程之间是有之间关系的。子进程从属于父进程,整个系统的进程是一个倒过来的树形结构,所有的进程都是从init进程创建来的。当进程结束的时候它的父进程会收回子进程的资源。这时会产生一个问题,当父进程创建子进程以后,两个进程是无序运行的。如果父进程先于子进程结束,那么子进程就会因为找不到父进程的进程号而无法通知父进程,导致资源无法释放。因原创 2009-12-17 14:58:00 · 1479 阅读 · 0 评论 -
8.1.2 进程环境和属性
8.1.2 进程环境和属性在Linux系统,C程序总是从main()函数开始的,当用户编写好的程序在运行的时候,操作系统会使用exec()函数运行程序,在调用main()函数之前,exec()系统调用会先调用一个特殊的启动例程,负责从操作系统内核读取程序的命令行参数,为main()函数准备好工作环境。由于历史的原因,大多数UNIX系统的main()函数定义如下: int main原创 2009-12-16 09:48:00 · 687 阅读 · 0 评论 -
14.5 小 结
14.5 小 结本章介绍了Bootloader的概念以及常见的两款Bootloader软件,重点分析了U-Boot的结构和启动代码,并且给出了U-Boot移植的分析。Bootloader是一种与硬件联系紧密的软件,在学习的时候要结合硬件手册,对照代码分析提高学习的效率。第15章将讲解Linux内核代码结构。原创 2009-12-17 17:12:00 · 616 阅读 · 0 评论 -
14.3.4 lowlevel_init标号
14.3.4 lowlevel_init标号lowlevel_init标号位于board/smdk2410/lowlevel_init.S文件,代码如下: 132 .globl lowlevel_init133 lowlevel_init:134 /* memory control configuration */135 /* make r0 relative t原创 2009-12-17 17:04:00 · 924 阅读 · 0 评论 -
14.3.3 cpu_init_crit标号
14.3.3 cpu_init_crit标号cpu_init_crit标号处的代码初始化ARM处理器关键的寄存器。代码如下: 228 /*229 *****************************************************************230 *231 * CPU_init_critical registers232 *原创 2009-12-17 17:03:00 · 1177 阅读 · 0 评论 -
14.1 初识Bootloader
14.1 初识Bootloader对于没有接触过嵌入式系统的人来说,Bootloader的功能虽然可以理解,但是缺乏一个直观的认识。本节以大家熟知的PC为例,介绍PC的启动工作流程,然后引入嵌入式Bootloader的概念,给读者一个感性的认识,帮助初学者揭开嵌入式系统Bootloader的面纱。14.1.1 PC(个人电脑)上的Bootloader不少初学者都会对标题有或多或少的原创 2009-12-17 16:30:00 · 1841 阅读 · 0 评论 -
8.1.7 进程编程实例
8.1.7 进程编程实例在本节的最后,给出一个多进程编程的综合实例,程序会创建两个进程,在父进程和子进程之间通过管道传递数据,父进程向子进程发送字符串exit表示让子进程退出,并且等待子进程返回;子进程查询管道,当从管道读出字符串exit的时候结束。实例8-7 进程编程实例 1 // process_demo.c2 #include 3 #include 4 #in原创 2009-12-17 15:19:00 · 690 阅读 · 0 评论 -
8.1.6 常用进程间通信的方法
8.1.6 常用进程间通信的方法在支持多进程的操作系统里,用户可以创建多个进程,分别处理不同的功能。多进程机制为处理不同的数据带来好处。但是,在实际处理过程中,经常需要在不同的进程之间传递数据。如有两个进程,一个读取不同用户的配置文件并且解析配置文件,另一个进程需要把每个用户的配置发送到远程的服务器,这样的两个进程需要数据的传递,这个时候就会用到进程间通信。Linux提供了多种进程间通信原创 2009-12-17 15:12:00 · 973 阅读 · 0 评论 -
8.1.3 创建进程
8.1.3 创建进程Linux系统通过fork()系统调用创建一个进程,fork()函数定义如下: #include #include pid_t fork(void); fork()系统调用在应用程序库里对应一个同名的fork()函数。fork()函数的定义很简单,但是初学者会感到不好理解,应注意分析多进程环境的特点。如图8-1所示为创建进程的过程。从图8-1中原创 2009-12-17 14:52:00 · 674 阅读 · 0 评论 -
8.3 小 结
8.3 小 结本章讲解了Linux应用程序开发最重要的两种技术:多进程和多线程。多进程和多线程技术是应用最广泛的技术之一,使用该技术可以并发处理业务流程,充分利用计算机资源提高业务处理能力。理解多进程和多线程最关键的是建立并发工作的概念,读者在学习的时候应该多实践,通过实践加深理解。第9章将讲解网络程序开发的相关内容。原创 2009-12-17 15:37:00 · 501 阅读 · 0 评论 -
第14章 深入Bootloader
第14章 深入BootloaderBootloader一词在嵌入式系统中应用广泛,中文意思可以解释为“启动加载器”。顾名思义,Bootloader是一个在系统启动时工作的软件。由于启动时候涉及硬件和软件的启动,所以Bootloader是一个涉及硬件和软件衔接的重要系统软件。本章从Bootloader的原理出发,分析Bootloader的基本功能,同时介绍了常见的Bootloader系统软件,原创 2009-12-17 16:27:00 · 1093 阅读 · 0 评论 -
14.3.7 main_loop()函数
14.3.7 main_loop()函数main_loop()函数做的都是与具体平台无关的工作,主要包括初始化启动次数限制机制、设置软件版本号、打印启动信息、解析命令等。(1)设置启动次数有关参数。在进入main_loop()函数后,首先是根据配置加载已经保留的启动次数,并且根据配置判断是否超过启动次数。代码如下: 295 void main_loop (void)296 {原创 2009-12-17 17:08:00 · 1189 阅读 · 0 评论 -
ARM嵌入式Linux系统开发详解——前言
前 言随着超大规模集成电路的发展,计算机处理器技术不断提高,计算机芯片的处理能力越来越强,体积越来越小,计算机技术应用到生活的方方面面。与人们日常生活打交道最多的就是嵌入式系统,从目前广泛使用的手机、MP3播放器到家用电器,嵌入式系统的应用无处不在。嵌入式系统的开发占整个计算机系统开发的比重也越来越高。嵌入式系统开发与传统的PC程序开发不同。嵌入式系统开发涉及软件硬件的开发,是一个协同工原创 2009-12-16 09:37:00 · 1677 阅读 · 0 评论 -
14.3.6 start_armboot()函数
14.3.6 start_armboot()函数start_armboot()函数主要初始化ARM系统的硬件和环境变量,包括Flash存储器、FrameBuffer、网卡等,最后进入U-Boot应用程序主循环。start_armboot()函数代码如下: 236 void start_armboot (void)237 {238 init_fnc_t **init_fnc原创 2009-12-17 17:07:00 · 1027 阅读 · 0 评论 -
14.3.2 reset标号
14.3.2 reset标号reset标号的代码在处理器启动的时候最先被执行。 106 /*107 * the actual reset code108 */109 110 reset:111 /*112 * set the cpu to SVC32 mode113 */114 mrs r0,cpsr原创 2009-12-17 17:01:00 · 903 阅读 · 0 评论