嵌入式软件开发简介以linux为例.ppt_第1页
嵌入式软件开发简介以linux为例.ppt_第2页
嵌入式软件开发简介以linux为例.ppt_第3页
嵌入式软件开发简介以linux为例.ppt_第4页
嵌入式软件开发简介以linux为例.ppt_第5页
已阅读5页,还剩218页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌入式软件开发简介 以linux为例,2,课程安排,嵌入式Linux开发环境搭建 嵌入式Linux概述 Linux快速入门 熟悉嵌入式开发平台 熟悉引导启动代码和内核的烧写 NFS环境构建,3,课程安排,嵌入式Linux下的应用程序开发 嵌入式Linux开发工具与开发流程 理解交叉编译 嵌入式Linux下的应用程序调试技巧 Make工程管理器,4,嵌入式系统的特点,嵌入式系统低功耗、体积小,专用性强。嵌入式系统与PC机的最大不同就是嵌入式CPU大多工作在为特定用户群设计的系统中,能够把PC机中许多由板卡完成的任务集成在芯片内部,从而有利于嵌入式系统设计趋于小型化。 为了提高执行速度和系统可靠性,嵌入式系统中的软件一般都固化在存储器芯片或单片机本身中,而不是存贮于磁盘等载体中。 嵌入式系统的硬件和软件都必须高效率地设计,系统要精简。操作系统一般和应用软件集成在一起。 对软件代码质量要求很高。应该尽最大可能避免死机的情况发生。 嵌入式系统开发需要专门的开发工具和开发环境。,5,如何选择嵌入式CPU?,ARM PowerPC MIPS Xscale DSP X86 ,6,典型的嵌入式操作系统,Linux uC/OS Windows CE VxWorks Palm OS Symbian,7,嵌入式系统开发流程,8,嵌入式系统开发的内容,9,嵌入式Linux开发模式,Linux,JTAG,CPU CORE,Flash,Target,Host,串口,网口,NFS模式,Root fs,10,Linux快速入门,11,Linux简介,Linus Torvalds于1991编写 Linux是一个Unix兼容的系统,大部分通用的Unix工具和程序都可以在Linux系统下运行。UNIX-堂兄 Linux表弟 使用GNU工具开发: gcc,glibc,binutils,make等 GNU = GNU is Not Unix GPL = General Public License,12,一些发行版,RedHat Fedora Core Suse Debian Ubuntu Cent OS Aisanux,13,认识Linux内核版本,主版本 1.0 2.0 2.2 2.4 2.6 2,3年更新 稳定版 2.0.40 2.2.12 2.4.18 2.6.7 2.6.30 1,2月更新 稳定版更新 1,2周更新,14,Linux体系结构,用户空间,内核空间,shell,命令、程序或shell脚本,文件 系统,I/O,中断 异常 处理,内存 管理,Cache,调度,系统调用(system calls),内核,15,内核结构,16,Linux优点,提供了先进的网络支持 多任务、多用户 符合IEEE POSIX标准 核心能仿真FPU 支持数十种文件系统格式 完全运行于保护模式 开放源代码 采用先进的内存管理机制,更加有效地利用物理内存,17,Linux分区,Linux分区的形式 Swap分区 根分区/ Boot分区 其他,18,Linux的基本命令,Shell命令行使用技巧 :Tab自动补齐、 ctrl+a+e等 cd:转换目录 ls:列出文件名(根目录浏览) ll:查看文件属性(文件属性与权限 ) cp:复制文件(cp /mnt/hgfs/share/*.* /root/) mv:移动文件(可用于文件或目录的改名) rm:删除文件(rm rf (目标)) mkdir:创建目录 rmdir:删除目录,19,Linux的基本命令(2),cat:显示文本文件 less/more:分屏显示文件 grep:查找字符串(ls all | grep *) head:显示文件开头 tail:显示文件结尾 sort:按次序显示文件 uniq:去掉文件中重复的行 diff:比较两个文件 file:测试文件内容,20,Linux的基本命令(3),echo:显示文本 date:显示时间和日期 gzip:压缩文件 gunzip:解压缩文件 bzip2:压缩文件 tar:打包和解包文件 whereis:查找命令 which:查找实用程序,21,Linux的基本命令(4),ps:列出进程 df :检查文件系统空间占用情况 du:显示磁盘空间的使用情况 kill:杀死进程 chmod :改变文件或目录的访问权限 chown:改变文件或目录的属主和组 chgrp:改变文件或目录所属的组 info:获得帮助,22,Linux的基本命令(5),pwd:显示当前工作目录的绝对路径 rpm:文件包管理 clear:清屏 ln:创建文件链接 who:列出系统上的用户名单 write:发送消息 talk:与其他用户通信 man:获取帮助,23,熟悉嵌入式开发平台 熟悉引导启动代码和内核的烧写,24,需要熟悉的内容,开发板硬件基本配置 开发板与PC机连接方式 PC机相关配置 熟悉bootloader的使用 深入理解开发内容 巩固开发流程,25,Bootloader烧写示范,Linux环境(虚拟机)简介 超级终端和DNW的配置 Bootloader的显示信息简介(标准BIOS) 内核、文件系统的演示,26,嵌入式Linux下的应用程序开发,27,开发工具-编辑器vi,vi的基本使用方法,输入模式,命令模式,28,vi-开始编辑,新增 (append) - a 从 光 标 所 在 位 置 後 面 开 始 新 增 资 料, 光 标 後 的 资 料 随 新 增 资 料 向 後 移 动。 - A 从 光 标 所 在 列 最 後 面 的 地 方 开 始 新 增 资 料。 插 入 (insert) - i 从 光 标 所 在 位 置 前 面 开 始 插 入 资 料, 光 标 後 的 资 料 随 新 增 资 料 向 後 移 动。 - I 从 光 标列 的 第 一 个 非 空 白 字 符 前 面 开 始 插 入 资 料。 开 始 (open) - o 在 光 标 所 在 列 下 新 增 一 列 并 进 入 输 入 模 式。 - O 在 光 标 所 在 列 上 方 新 增 一 列 并 进 入 输 入 模 式。,29,vi-删除与修改,x 删除光标所在字符。 dd 删除光标所在的列。 r 修改光标所在字符,r後接著要修正的字符 R进入取代状态,新增资料会覆改原先资料, 直到按ESC回到指令模式下为止。 s 删除光标所在字符,并进入输入模式。 S 删除光标所在的列,并进入输入模式。,30,vi-退出命令,不保存退出 不保存强制性退出 保存编辑 存入文件filename 中 强制性存入文件filename 中 ()保存并退出(shift+zz),31,vi-光标移动命令,移动到当前单词的开始 移动到当前单词的结尾 向前移动一个单词 向前移动一个字符 向上移动一行 向下移动一行 向后移动一个字符,32,vi-改变与替换操作命令,替换光标所在的字符 替换字符序列 替换一个单词 同 替换光标所在的前一字符 替换自光标位置至行尾的所有字符 同 替换当前行,33,vi-拷贝与粘贴命令,将光标所在单词拷入剪贴板 将光标至行尾的字符拷入剪贴板 同 将当前行拷入剪贴板 将剪贴板中的内容粘贴在光标后 将剪贴板中的内容粘贴在光标前,利用Vi编写一个helloworld程序!,34,35,开发工具 -编译器GCC,全称为GNU CC ,GNU项目中符合ANSI C标准的编译系统 编译如C、C+、Object C、Java、Fortran、Pascal、Modula-3和Ada等多种语言 一个交叉平台编译器 ,适合在嵌入式领域的开发编译,36,GCC编译器,GNU Compiler Collection C, C+, Objective-C, Fortran, Java, Ada ,GCC 4.2.2,GCC 2.95,July 31, 1999,GCC 3.0,June 18, 2001,GCC 3.2,August 14, 2002,GCC 3.3,May 13, 2003,Oct 9, 2007,December 3, 1997,37,GCC简介,gcc所支持后缀名解释 .c C原始程序 .C/.cc/.cxx C+原始程序 .m Objective-C原始程序 .i 已经过预处理的C原始程序 .ii 已经过预处理的C+原始程序 .s/.S 汇编语言原始程序 .h 预处理文件(头文件) .o 目标文件 .a/.so 编译后的库文件,38,编译器的作用,Gcc的编译流程分为四个步骤 预处理(Pre-Processing) 编译(Compiling) 汇编(Assembling) 链接(Linking),39,“hello”的演变历程,40,理解交叉编译及环境建立,41,GCC 交叉编译器,GNU Binutils GNU Binutils 的主要工具有两个,一个是连接程序ld,另外一个是汇编程序as。其主要目的是为GNU 系统,提供汇编和连接工具。 GNU GCC GNU GCC 就是上面提到的GCC,GCC 主要是为GNU 系统提供C 编译器。现在支持多种语言,这其中包括C/C+、Fortran、Java、Objective-C、甚至还有Ada。 GNU GLibc 用于定义系统调用和其它一些基本的函数调用。,42,GCC交叉编译器的生成,第1步,取得Binutils、GCC、Glibc 源码。 第2步,配置并编译Binutils 取得我们所需要的汇编和连接程序。 第3步,配置并编译GCC 源码生成GCC 编译器。一般是C 编译器首先生成,然后以这个为基础在结合下一步生成的Glibc 的C 函数库,再编译生成其它编译器。 第4步,配置Glibc 并编译生成Glibc 的C 函数库。 第5步,再次配置和编译GCC 源码,生成其它语言的编译器,如C+编译器等。,43,工具链代码结构,44,TARGET常用的值,45,交叉编译流程,crosstool介绍,crosstool是由Dan Kegel开发的一套脚本程序,可以自动编译不同版本的gcc、glibc,并做出测试。 在crosstool软件包中,提供了从互联网下载软件包的脚本,例如glibc-get.sh脚本可以下载glibc软件包。 有关crosstool的详细信息,读者可以访问其官方网站和其他一些网络资源: /crosstool/ /crosstool/crosstool-0.42/doc/crosstool-howto.html /doc/debian-policy/,46,,47,环境变量,Linux环境变量PATH 有关配置文件 etc/profile .bashrc,48,设置交叉编译器的环境变量,etc/profile文件中的PATH定义了找存放命令的路径,若把交叉编译器的路径在PATH中进行定义,则执行命令时就可以找到对应的命令。 示例:使用2.95.3版本的交叉编译器 将usr/local/arm/2.95.3/bin路径添加到etc/profile文件中,并用将原来的3.4.4的屏蔽(如果有的话),然后在etc路径下执行source profile。然后arm-linux-gcc v,如果显示是2.9.53。则说明环境配置成功。 更改环境变量有几种方法,其中之一是更改etc/profile文件(开机启动时配置)中的PATH,将相冲突的屏蔽掉。 另一种方法是重新定义PATH,然后用export导出(export命令可以修改,但重启之后?):可编辑/etc/bashrc文件,在最后增加路径 export PATH=/usr/local/arm/2.95.3/bin:|$PATH,则以后编译内核或其它程序均可用arm-linux- 来制定交叉编译器。,49,嵌入式Linux下的 应用程序调试技巧,50,调试器-Gdb调试流程,首先使用gcc对test.c进行编译,注意一定要加上选项-g # gcc -g test.c -o test # gdb test GNU gdb Red Hat Linux (-1.21rh) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type “show copying“ to see the conditions. There is absolutely no warranty for GDB. Type “show warranty“ for details. This GDB was configured as “i386-redhat-linux-gnu“.Using host libthread_db library “/lib/libthread_db.so.1“. (gdb),51,Gdb调试流程,查看文件 (gdb) l 设置断点 (gdb) b 6 查看断点情况 (gdb) info b 运行代码 (gdb) r,查看变量值 (gdb) p n 单步运行 (gdb) n (gdb) s 恢复程序运行 (gdb) c 帮助 (gdb) help command,52,Gdb的使用切记点,在Gcc编译选项中一定要加入-g。 只有在代码处于“运行”或“暂停”状态时才能查看变量值。 设置断点后程序在指定行之前停止,53,Gdb调试,运行被调试程序,设置所有的能影响该程序的参数和变量。 保证被调试程序在指定的条件下停止运行。 当被调试程序停止时,让开发工程师检查发生了什么。 根据每次调试器的提示信息来做响应的改变,以便修正某个错误引起的问题,54,嵌入式程序调试-NFS,熟悉Uboot的烧写方法和使用 按照实验指导配置tftp服务 按照实验指导配置NFS服务 利用NFS调试经交叉编译后的程序,55,Makefile简介,56,工程管理器-Make,工程管理器,顾名思义,是指管理较多的文件 Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件文件的内容来执行大量的编译工作 Make将只编译改动的代码文件,而不用完全编译。,57,Makefile基本结构,Makefile是Make读入的唯一配置文件 由make工具创建的目标体(target),通常是目标文件或可执行文件 要创建的目标体所依赖的文件(dependency_file) 创建每个目标体时需要运行的命令(command) Makefile格式 target: dependency_files command 例子 hello.o: hello.c hello.h gcc c hello.c o hello.o,58,Makefile规则,隐式规则 隐含规则能够告诉make怎样使用传统的技术完成任务,这样,当用户使用它们时就不必详细指定编译的具体细节,而只需把目标文件列出即可 C编译:.c变为.o $(CC) c $(CPPFLAGS) $(CFLAGS) C+编译:.cc或.C变为.o $(CXX) -c $(CPPFLAGS) $(CXXFLAGS),59,Makefile规则,模式规则 模式规则是用来定义相同处理规则的多个文件的。它不同于隐式规则,隐式规则仅仅能够用make默认的变量来进行操作,而模式规则还能引入用户自定义变量,为多个文件建立相同的规则,从而简化了Makefile的编写 模式规则的格式类似于普通规则,这个规则中的相关文件前必须用“%”标明,60,Make使用,直接运行make 选项 -C dir读入指定目录下的Makefile-f file读入当前目录下的file文件作为Makefile -i忽略所有的命令执行错误 -I dir指定被包含的Makefile所在目录 -n只打印要执行的命令,但不执行这些命令 -p显示make变量数据库和隐含规则 -s在执行命令时不显示命令 -w如果make在执行过程中改变目录,打印当前目录名,61,Autotools简介,对于一个较大的项目而言编写Makefile难度较大 autotools系列工具只需用户输入简单的目标文件、依赖文件、文件目录等就可以轻松地生成Makefile autotools工具还可以完成系统配置信息的收集,从而可以方便地处理各种移植性的问题 Linux上的软件开发一般都用autotools来制作Makefile,62,autotools使用流程,63,使用Makefile,make 键入make默认执行make all命令,即目标体为all make install 把该程序安装到系统目录中去 make clean 清除之前所编译的可执行文件及目标文件(object file, *.o) make dist 将程序和相关的文档打包为一个压缩文档以供发布,Shell脚本简介,Shell脚本的本质,编译型语言 解释型语言 Shell脚本语言是解释型语言 Shell脚本的本质: Shell命令的有序集合。,shell 编程的基本过程,基本过程分为三步:,Step1. 建立 shell 文件 包含任意多行操作系统命令或shell命令的文本文件;,Step2. 赋予shell文件执行权限 用chmod命令修改权限;,Step3. 执行shell文件 直接在命令行上调用shell程序.,Step1: 建立shell文件 (可用任何建立文本文件的方法) $ cat prog1 who | grep $1,Step2: 赋予执行权限: (初始文本文件无执行权限) $ chmod 740 prog1,Step3: 执行该shell程序 $ prog1 wdl prog1: not found (shell在标准搜索目录中找不到prog1命令),Step4: 指定路径或修改环境变量PATH后执行shell程序 $ ./prog1 wdl wdl tty06 Feb 8 09:12,实例,Shell变量,Shell允许用户建立变量存储数据,但不支持数据类型(整型、字符、浮点型),将任何赋给变量的值都解释为一串字符 Variable=value 命名规则同C+中的命名规则 count=1 Echo $count DATE=date Echo $DATE,shell变量,Bourne Shell主要有如下三种变量: 用户自定义变量 位置变量即 shell script之参数 环境变量,用户自定义变量,在shell编程中通常使用全大写变量,方便识别 $ COUNT=1 变量的调用:在变量前加$ $ echo $HOME Linux Shell/bash从右向左赋值 $Y=y $ X=$Y $ echo $X y 使用unset命令删除变量的赋值 $ Z=hello $ echo $Z hello $ unset Z $ echo $Z,位置变量,$0 与键入的命令行一样,包含脚本文件名 $1,$2,$9 分别包含第一个到第九个命令行参数 $# 包含命令行参数的个数 $ 包含所有命令行参数:“$1,$2,$9” $? 包含前一个命令的退出状态 $* 包含所有命令行参数:“$1,$2,$9” $ 包含正在执行进程的ID号,shell环境变量,CDPATH:用于cd命令的查找路径 HOME: /etc/passwd文件中列出的用户主目录 IFS:Internal Field Separator,默认为空格,tab及换行符 MAIL:/var/mail/$USERNAME mail等程序使用 PATH :路径 PS1,PS2:默认提示符($)及换行提示符() TERM:终端类型,常用的有vt100,ansi,vt200,xterm等,文件测试,-d name 测试name 是否为一个目录 -f name 测试name 是否为普通文件 -L name 测试name 是否为符号链接 -r name 测试name 文件是否存在且为可读 -w name 测试name 文件是否存在且为可写 -x name 测试name 文件是否存在且为可执行 -s name 测试name 文件是否存在且其长度不为0 f1 -nt f2 测试f1 是否比f2 更新 f1 -ot f2 测试f1 是否比f2 更旧,ifthenfi 语法结构: if 表达式 then 命令表 fi 如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句. if和fi是条件语句的语句括号, 必须成对使用;命令表中的命令可以是一条, 也可以是若干条.,条件语句,caseesac 多路分支语句case用于多重条件测试, 语法结构清晰自然. 其语法结构为: case 字符串变量 in 模式1) 命令表1 ; 模式2) 命令表2 ; 模式n) 命令表n ; esac,case语句只能检测字符串变量,各模式中可用文件名元字符,以右括号结束,命令表以单独的双分号行结束,退出case语句,模式 n常写为字符* 表示所有其它模式,最后一个双分号行可以省略,多路分支语句,fordodone 当循环次数已知或确定时, 使用for循环语句来多次执行一条或一组命令。 循环体由语句括号do和done来限定。格式为: for 变量名 in 单词表 do 命令表 done 变量依次取单词表中的各个单词, 每取一次单词, 就执行一次循环体中的命令. 循环次数由单词表中的单词数确定. 命令表中的命令可以是一条, 也可以是由分号或换行符分开的多条。 如果单词表是命令行上的所有位置参数时, 可以在for语句中省略 “in 单词表” 部分。,循环语句,whiledodone 语法结构为: while 命令或表达式 do 命令表 done while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。 while语句的退出状态为命令表中被执行的最后一条命令的退出状态。,循环语句,78,实验内容,熟悉开发环境的搭建 熟悉BIOS、Uboot的使用,NFS的配置 编写简单的C程序 使用GDB调试有问题的C代码 编写简单的Makefile 编写简单的SHELL脚步,Bootloader,,80,内容提纲,什么是Bootloader,Bootloader是硬件启动的引导程序,是启动操作系统的根本; 是在操作系统内核或用户应用程序运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用准备好环境; 在一般典型的系统中,整个系统的加载启动任务就完全由Bootloader来完成。,,81,Bootloader不属于操作系统内核,采用汇编语言编写,因此针对不同的CPU体系结构,这一部分代码不具有可移植性; 在移植操作系统时,这部分代码必须加以改写。 Bootloader不但依赖于CPU的体系结构,而且依赖于嵌入式系统板级设备的配置。,Bootloader的特点,启动加载模式:在这种模式下,Bootloader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。 下载模式:在这种模式下,目标机上的Bootloader将通过串口或网络等通信手段从开发主机(Host)上下载内核映像和根文件系统映像等到RAM中。然后可以再被 Bootloader写到目标机上的固态存储媒质中,或者直接进行系统的引导。,Bootloader的操作模式,初始化硬件 将操作系统内核从Flash拷贝到SDRAM中,如果是压缩格式的内核,还要解压缩 改写系统的内存映射,原先Flash起始地址映射为0地址,这时需要将RAM的起始地址映射为0 提供Linux内核的启动参数 启动Linux内核 设置堆栈指针并将bss段清零将来执行C语言程序和调用子函数时要用到 改变pc值,使得CPU开始执行真正的操作系统内核。,Bootloader的特征,Bootloader的启动,系统加电或复位后,所有CPU都会从某个地址开始执行 嵌入式系统的开发板都要把板上ROM或FLASH映射到这个地址。因此,必须把Bootloader程序存储在相应的FLASH位置。系统加电后,CPU将首先执行它。,,85,屏蔽所有的中断。为中断提供服务通常是 OS 设备驱动程序的责任,因此在 Boot Loader 的执行全过程中可以不必响应任何中断 设置 CPU 的速度和时钟频率 RAM 初始化。包括正确地设置系统的内存控制器的功能寄存器以及各内存库控制寄存器等 初始化 LED。其目的是表明系统的状态。如果板子上没有 LED,可以通过初始化 UART 向串口打印 Bootloader 的 Logo 字符信息来完成这一点 关闭CPU内部I/D cache 为加载 stage2 准备 RAM 空间,跳转到 stage2的C入口点,Bootloader的第一阶段,初始化本阶段要使用到的硬件设备; 检测系统内存映射; 将内核映像和根文件系统映像从Flash读到RAM; 为内核设置启动参数; 调用内核。,Bootloader的第二阶段,一些bootloader介绍,Configuration file /boot/grub/menu.lst /boot/grub/grub.conf default=0 timeout=10 splashimage=(hd0,1)/boot/grub/splash.xpm.gz title MicroSoft Windows XP rootnoverify (hd0,0) chainloader +1 title Red Hat Linux (2.4.20-8) root (hd0,1) kernel /boot/vmlinuz-2.4.20-8 ro root=LABEL=/ initrd /boot/initrd-2.4.20-8.img,配置GRUB,U-Boot是ARM bootloader标准 armboot 加入到 ppcboot 形成了 u-boot 支持arm720, arm920, arm926, sa1100, xscale / Blob blob是LART工程使用的bootloader 移植到多个ARM平台上 http:/www.lart.tudelft.nl/lartware/blob Redboot,ARM Bootloaders,FS2410开发板提供的BIOS,,91,0号功能:USB下载,1号功能:串口下载,2号功能:执行NAND Flash的烧写,3号功能:从NAND Flash启动程序,4号功能:擦除NAND Flash分区,5号功能:烧写Nor Flash,6号功能:设置启动参数,7号功能:设置自启动参数,DRAM控制器,DRAM芯片不能向其它微处理器总线资源那样直接读写,它们需要特殊的硬件控制器使能读写循环。 设置DRAM控制器需要详细了解DRAM体系结构、控制器本身、 DRAM芯片使用的规范和全面的硬件设计。 Bootloader首先要完成的就是使能内存子系统。初始化内存以后,内存可以作为一种资源进行使用。,,92,,93,内容提纲,u-boot(Universal Boot Loader)是德国DENX小组的开发用于多种嵌入式CPU的bootloader程序。遵循GPL条款; 从FADSROM、8xxROM 、PPCBOOT逐步发展演化而来; 当前版本号:见include/version.h中的定义。,U-boot介绍,平台相关 board, cpu, lib_ppc, lib_arm, include 平台无关 common, net, fs, drivers 工具和文档 tools, doc,U-Boot程序结构,U-Boot程序结构,U-Boot程序结构,在 Flash 中运行汇编程序,将 Flash 中的启动代码部分复制到 SDRAM 中,同时创造环境准备运行 C 程序; 在 SDRAM 中执行,对硬件进行初始化; 设置内核参数的标记列表,复制镜像文件,进入内核的入口函数,U-Boot 启动过程的几个阶段,99,初始化硬件 设置UART 设置网口 设置USB 检测存储器 设置启动参数 内核硬件信息 波特率 跳转到Linux内核的首地址 消亡,BootLoader的生命周期,设置异常的入口地址和异常处理函数; 配置 PLLCON 寄存器,确定系统的主频; 屏蔽看门狗和中断;初始化 I/O 寄存器; 关闭 MMU 功能; 调用 /board/smdk2410 中的lowlevel_init.S ,初始化存储器空间,设置刷新频率; 将 U-Boot 的内容复制到 SDRAM 中; 设置堆栈的大小( ldr pc, _start_armboot ) ; 设置程序编译连接的起始地址( config.mk: TEXT_BASE = 0x33F80000 )。,U-Boot入口函数start.S,系统复位代码 ldr pc, _start_armboot _start_armboot: .word start_armboot 表示u-boot完成cpu初始化,将跳转到C程序中间。 start_armboot完成设备初始化过程,进入main_loop循环。 start_armboot - lib_arm/board.c,cpu/arm920t/start.S,mrs r0,cpsr bic r0,r0,#0x1f ; 位清零 orr r0,r0,#0xd3 ; 逻辑或0xd3= 1101 0011 msr cpsr,r0,复位,模式位含义,ldr r0, =pWTCON mov r1, #0x0 str r1, r0,关闭看门狗,mov r1, #0xffffffff ldr r0, =INTMR str r1, r0,关闭中断,mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */,刷新指令/数据缓存,mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 clear bits 13, 9:8 (-V- -RS) bic r0, r0, #0x00000087 clear bits 7, 2:0 (B- -CAM orr r0, r0, #0x00000002 set bit 2 (A) Align orr r0, r0, #0x00001000 set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0,禁用MMU和缓存,板级相关,/board/lowlevel_init.S mov ip, lr bl lowlevel_init mov lr, ip mov pc, lr,设置RAM,.globl lowlevel_initlowlevel_init: ldr r0, =SMRDATA ldr r1, _TEXT_BASE sub r0, r0, r1 ldr r1, =BWSCON add r2, r0, #13*40: ldr r3, r0, #4 str r3, r1, #4 cmp r2, r0 bne 0b,lowlevel_init,调试u-boot时,开始一般是让它在RAM中运行,当RAM运行通过后才将其固化到FLASH中;这样如果我们当前的代码是通过BDI2000等Load到内存直接运行的话,u-boot就不需要去将自己从Flash搬移到内存了;而如果u-boot是固化在Flash中在CPU复位后由第一个片选信号指向开始执行的话,则有一个从Flash搬移到内存的过程。,重定位(Relocate)的概念,relocate: /* relocate U-Boot to RAM */ adr r0, _start /*当前代码的地址信息 */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* dont reloc during debug */ beq stack_setup ldr r2, _armboot_start ldr r3, _armboot_end sub r2, r3, r2 /* r2 - size of armboot */ add r2, r0, r2 /* r2 - source end address */ copy_loop: ldmia r0!, r3-r10 /* copy from source address r0 */ stmia r1!, r3-r10 /* copy to target address r1 */ cmp r0, r2 /* until source end addreee r2 */ ble copy_loop,重定位的实现,lib_arm/board.c void start_armboot (void) size = flash_init (); display_flash_config (size); for (;) main_loop (); ,start_armboot,系统调用 memcpy() 函数将内核从 flash 和 ramdisk 复制到 SDRAM 中,具体如下: memcpy(void *)0x30008000, (void *)0x40000, 0x100000) ; / 复制数据块 memcpy(void *)0x30800000, (void *)0x140000, 0x440000) ; / 复制数据块,调用内核启动函数 do_bootm_linux(),0x30008000 是内核在 SDRAM 中的起始地址 0x40000 是内核在 Flash 中的位置 0x100000 是数据块的大小,编译U-boot,U-boot的源码是通过gcc和Makefile组织编译的。顶层目录下的Makefile首先可以设置开发板的定义,然后递归地调用各级子目录下的Makefile,最后把编译过的程序链接成u-boot映像。 顶层目录下的Makefile 它负责u-boot整体配置编译。每一种开发板在Makefile都需要有板子配置的定义。 配置u-boot: make smdk2410_config 编译: make,,114,U-BOOT编译生成的映像文件,,115,U-boot命令介绍,Printenv 打印环境变量。 Uboot printenv baudrate=115200 ipaddr= ethaddr=12:34:56:78:9A:BC serverip=,,116,U-boot命令介绍,setenv 设置新的变量 Uboot setenv myboard AT91RM9200DK Uboot printenv baudrate=115200 ipaddr= ethaddr=12:34:56:78:9A:BC serverip= myboard=AT91RM9200DK Environment size: 102/8188 bytes saveenv 将当前定义的所有的变量及其值存入flash中。,,117,U-boot命令介绍,tftp 通过网络下载程序 Uboot setenv ethaddr 12:34:56:78:9A:BC Uboot setenv ipaddr Uboot setenv serverip 54 Uboot tftp 20000000 application.bin Uboot tftp 30200000 zImage Loadb 通过串口Kermit协议下载二进制数据。,,118,U-boot命令介绍,md 显示内存区的内容。 mm 修改内存,地址自动递增。 nm 修改内存,地址不自动递增。 mw 填充内存。 mtest 测试内存。 cp 拷贝一块内存到另一块。 cmp 比较两块内存区。 mw 0x32000000 ff 0x10000,,119,U-boot命令介绍,Protect 写保护操作 protect on 1:0-3(就是对第一块FLASH的0-3扇区进行保护) protect off 1:0-3取消写保护 erase 擦除扇区 erase: 删除FLASH的扇区 erase 1:0-2(就是对每一块FLASH的0-2扇区进行删除),,120,U-boot命令介绍,run 执行设置好的脚本 Uboot setenv flashit tftp 20000000 mycode.bin; erase 10020000 1002FFFF;cp.b 20000000 10020000 8000 Uboot saveenv Uboot run flashit bootcmd 保留的环境变量 如果定义了该变量,在autoboot模式下,将会执行该脚本的内容。,,121,U-boot命令介绍,go 执行内存中的二进制代码,一个简单的跳转到指定地址 bootm 执行内存中的二进制代码 要求二进制代码为制定格式的。通常为mkimage处理过的二进制文件。启动Uboot工具制作的压缩Linux内核 bootp 通过网络启动,需要提前设置好硬件地址。,,122,U-boot命令介绍,usb reset 复位(rescan) USB 控制器 usb stop f - 停止USB usb tree - 显示USB 设备树 usb info dev 显示可用的USB设备 usb storage - 显示USB存储设备详细信息 usb dev dev - show or set current USB storage device usb part dev - print partition table of one or all USB storage devices usb read addr blk# cnt - read cnt blocks starting at block blk# to memory address addr,,123,U-boot命令介绍,nand info: 显示NAND 设备 nand device dev:显示或设置当前设备 nand bad 显示坏块 nand read.jffs2s addr off size nand write.jffs2 addr off size nand erase clean off size nand read.oob addr off size nand write.oob addr off size,,124,U-boot命令介绍,nfs nfs 32000000 :aa.txt 把中的NFS文件系统中的aa.txt 读入内存0x32000000处。,,125,配置编译LINUX内核,内容提纲, wget /pub/linux/kernel/. wget /././linux-*.bz2.sign gpg verify linux-2.xx.tar.bz2.sign tar jxvf linux-2.xx.tar.bz2,下载内核,内核配置与编译,使用补丁升级 如果你有一个版本可以到下载相应的升级补丁 如果想从2.4.26 升级到 2.4.27 则可以 wget -c /pub/linux/kernel/v2.4/patch-2.4.27.bz2 wget /pub/linux/kernel/v2.4/patch-2.4.27.bz2.sign 如果想从 2.6.11 升级到 2 则可以 wget /pub/linux/kernel/v2.6/patch-2.bz2 wget /pub/linux/kernel/v2.6/patch-2.bz2.sign 确认下载的补丁是否正确 gpg verify patch-2.4.27.bz2.sign 为内核代码打补丁 cd linux2.4.26/ bzcat /patch-2.4.27.bz2 | patch -p1 cd mv linux-2.4.26 linux-2.4.27,init kernel mm ipc lib fs net drivers,Linux内核结构,arch,i386 arm ppc m68k sh ,include,查看完整命令行 make V = 1 删除生成的文件 make clean 删除全部生成的文件,包括.config make mrproper,编译技巧,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论