第八次.ppt
- 文档编号:11476257
- 上传时间:2023-06-01
- 格式:PPT
- 页数:59
- 大小:1,010.50KB
第八次.ppt
《第八次.ppt》由会员分享,可在线阅读,更多相关《第八次.ppt(59页珍藏版)》请在冰点文库上搜索。
1,第5章嵌入式Linux应用程序开发,5.1开发环境的建立5.2Linux及开发工具的使用5.3引导程序的移植5.4Linux操作系统的移植5.5应用程序的调试5.6综合训练:
建立嵌入式操作系统,2,Vi编辑器的使用,1工作模式Vi是“Visualinterface”的简称,可以执行输出、删除、查找、替换、块操作等众多文本操作,而且用户可以根据自己的需要对其进行定制。
Vi有三种基本工作模式:
命令行模式、文本输入模式和末行模式。
3,工作模式,命令行模式任何时候,不管用户处于何种模式,只要按一下键,即可使Vi进入命令行模式;我们在shell环境(提示符为$)下输入启动命令“vi”,进入编辑器时,也是处于该模式下。
在该模式下,用户可以输入各种合法的Vi命令,用于管理自己的文档。
此时从键盘上输入的任何字符都被当做编辑命令来解释,若输入的字符是合法的Vi命令,则Vi在接受用户命令之后完成相应的动作。
但需注意的是,所输入的命令并不在屏幕上显示出来。
若输入的字符不是Vi的合法命令,Vi会响铃报警。
文本输入模式在命令模式下输入插入命令i、附加命令a、打开命令o、修改命令c、取代命令r或替换命令s都可以进入文本输入模式。
在该模式下,用户输入的任何字符都被Vi当做文件内容保存起来,并将其显示在屏幕上。
在文本输入过程中,若想回到命令模式下,按Esc键即可。
末行模式在命令模式下,用户按“:
”键即可进入末行模式下,此时Vi会在显示窗口的最后一行,显示一个“:
”作为末行模式的提示符,等待用户输入命令。
多数文件管理命令都是在此模式下执行的。
末行命令执行完后,Vi自动回到命令模式。
4,2进入在提示符“$”后键入Vi和想要编辑的文件名,便可进入Vi。
例如:
$viexample.c如果只键入Vi,而不带文件名,也可以进入Vi,之后在光标处键入文件内容。
进入Vi后,首先进入的就是命令模式,进入Vi时,用户不仅可以指定一个待编辑的文件名,而且还有许多附加操作。
如果希望在进入Vi之后,光标处于文件中特定的某行上,可在Vi后加上选项+n,其中n为指定的行数。
例如:
$vi+5example1.c,5,3退出在命令模式中,连按两次大写字母Z,若当前编辑的文件曾被修改过,则Vi保存该文件后退出,返回到shell;若当前编辑的文件没被修改过,则Vi直接退出,返回到shell。
在末行模式下,输入命令:
:
wVi保存当前编辑文件,但并不退出,而是继续等待用户输入命令。
在使用w命令时,可以再给编辑文件起一个新的文件名。
:
wnewfile此时Vi将把当前文件的内容保存到指定的newfile中,而原有文件保持不变。
在末行模式下,输入命令:
:
q系统退出Vi返回到shell。
若在用此命令退出Vi时,编辑文件没有被保存,则Vi在显示窗口的最末行显示如下信息:
Nowritesincelastchange(use!
tooverrides)提示用户该文件被修改后没有保存,然后Vi并不退出,继续等待用户命令。
若用户就是不想保存被修改后的文件而要强行退出Vi时,可使用命令:
:
q!
6,Linux下C语言编程,1文件读写当需要打开一个文件进行读写操作的时候,可以使用系统调用函数open。
文件操作完成后,调用close函数关闭文件。
intopen(constchar*pathname,intflags);intopen(constchar*pathname,intflags,mode_tmode);intclose(intfd);open函数有两个形式,在此只介绍第一种方式。
其中pathname是我们要打开的文件名,包含路径名称,默认是在当前路径下。
Flags取值可以是下面的一个值或者是几个值的组合。
O_RDONLY:
以只读的方式打开文件;O_WRONLY:
以只写的方式打开文件;O_RDWR:
以读写的方式打开文件;O_APPEND:
以追加的方式打开文件;O_CREAT:
创建一个文件;要采用open的第二种形式;O_EXEC:
使用该选项时,如果使用了O_CREAT而且文件已经存在,就会发生一个错误;O_NOBLOCK:
以非阻塞的方式打开一个文件;O_TRUNC:
如果文件已经存在,则删除文件的内容。
如果打开文件成功,open会返回一个文件描述符。
以后对文件的所有操作就可以对这个文件描述符进行操作了。
当操作完成以后,要关闭文件时,只要调用close就可以了,其中fd是要关闭的文件描述符。
7,文件打开后,就可以调用函数read和write进行文件的读写。
ssize_tread(intfd,void*buffer,size_tcount);ssize_twrite(intfd,constvoid*buffer,size_tcount);fd是要进行读写操作的文件描述符,buffer是要写入文件内容或读出文件内容的内存地址,count是要读写的字节数。
对于普通的文件,read从指定的文件(fd)中读取count个字节到buffer缓冲区中,同时返回count。
如果read读到了文件的结尾或者被一个信号所中断,返回值会小于count。
如果是由信号中断引起返回,而且没有读出数据,read会返回1,且设置errno为EINTR。
当程序读到了文件结尾的时候,read会返回0。
write从buffer中写count字节到文件fd中,成功时返回实际所写的字节数。
8,#defineBUFFER_SIZE1024intmain(intargc,char*argv)intfrom_fd,to_fd;intbytes_read,bytes_write;charbufferBUFFER_SIZE;char*ptr;if(argc!
=3)fprintf(stderr,Usage:
%sfromfiletofilea,argv0);exit
(1);if(from_fd=open(argv1,O_RDONLY)=-1)fprintf(stderr,Open%sError:
%s,argv1,strerror(errno);exit
(1);if(to_fd=open(argv2,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR)=-1)fprintf(stderr,Open%sError:
%s,argv2,strerror(errno);exit
(1);while(bytes_read=read(from_fd,buffer,BUFFER_SIZE)if(bytes_read=-1),9,2文件属性文件具有各种各样的属性,除了上面提到的文件权限以外,文件还有创建时间、大小等属性。
有时候要判断文件是否可以进行某种操作,此时可以使用access函数。
intaccess(constchar*pathname,intmode);其中,pathname是文件名称,mode是所要判断的属性。
可以取以下值或者是其组合:
R_OK文件可以读;W_OK文件可以写;X_OK文件可以执行;F_OK文件存在。
当测试成功时,函数返回0;如果有一个条件不符时,返回1。
如果要获得文件的其他属性,可以使用函数stat或者fstat。
intstat(constchar*file_name,structstat*buf);intfstat(intfiledes,structstat*buf);structstatdev_tst_dev;/*设备*/ino_tst_ino;/*节点*/mode_tst_mode;/*模式*/nlink_tst_nlink;/*硬连接*/uid_tst_uid;/*用户ID*/gid_tst_gid;/*组ID*/dev_tst_rdev;/*设备类型*/off_tst_off;/*文件字节数*/unsignedlongst_blksize;/*块大小*/unsignedlongst_blocks;/*块数*/time_tst_atime;/*最后一次访问时间*/time_tst_mtime;/*最后一次修改时间*/time_tst_ctime;/*最后一次改变时间(指属性)*/;,10,stat用来判断没有打开的文件,而fstat用来判断打开的文件。
使用最多的属性一般是st_mode,通过该属性可以判断给定的文件是一个普通文件,还是一个目录或者连接。
可以使用下面几个宏来判断:
S_ISLNK(st_mode),是否是一个连接;S_ISREG,是否是一个常规文件;S_ISDIR,是否是一个目录;S_ISCHR,是否是一个字符设备;S_ISBLK,是否是一个块设备;S_ISFIFO,是否是一个FIFO文件;S_ISSOCK,是否是一个SOCKET文件。
11,3目录文件的操作在编写程序的时候,有时候想得到当前的工作路径。
C库函数提供了getcwd来解决这个问题:
char*getcwd(char*buffer,size_tsize);如果提供一个size大小的buffer,getcwd会把当前的路径拷贝到buffer中,如果buffer太小,函数会返回1和一个错误号。
Linux提供了大量的目录操作函数,下面列出了几个比较简单和常用的函数:
intmkdir(constchar*path,mode_tmode);DIR*opendir(constchar*path);structdirent*readdir(DIR*dir);voidrewinddir(DIR*dir);intclosedir(DIR*dir);mkdir就是创建一个目录,opendir打开一个目录为以后读做准备,readdir读一个打开的目录,rewinddir是用来重读目录的,closedir是关闭一个目录。
12,下面的程序有一个输入参数,如果这个参数是一个文件名,输出这个文件的大小和最后修改的时间;如果是一个目录,输出这个目录下所有文件的大小和修改时间。
staticintget_file_size_time(constchar*filename)structstatstatbuf;if(stat(filename,13,5.3引导程序的移植,嵌入式软件开发顺序:
引导程序Linux内核编译驱动程序开发应用程序在掌握GNU开发工具后,就需要对系统的引导程序进行移植了。
嵌入式的引导程序是与处理器体系结构紧密联系的,是嵌入式系统开发的难点之一,同时也是系统运行的一个基本前提条件,没有这段和硬件紧密相连的代码,多么精悍的内核也发挥不了作用。
14,嵌入式Linux的引导机理分析,一个嵌入式软件系统通常可以分为引导程序BootLoader、操作系统内核、文件系统和用户应用程序4个层次。
1BootLoader工作原理BootLoader是系统加电启动运行的第一段软件代码。
通过PC的体系结构我们可以知道,PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的引导程序一起组成。
BIOS在完成硬件检测和资源分配后,将硬盘MBR中的引导程序读到系统的RAM中,然后将控制权交给引导程序。
引导程序的主要运行任务是将内核映像从硬盘上读到RAM中,然后跳转到内核的入口点去运行,也即开始启动操作系统。
由于在嵌入式系统中,通常并没有像BIOS那样的固件程序(有的嵌入式系统也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。
对于一个嵌入式系统来说,可能有的包括操作系统,有的小型系统也可以只包括应用程序,但是在这之前都需要BootLoader为它准备一个正确的环境。
通常,BootLoader是依赖于硬件而实现的,特别是在嵌入式领域,为嵌入式系统建立一个通用的BootLoader是很困难的。
但是可以归纳一些通用的概念出来,以便简化特定BootLoader的设计与实现。
简单地说,BootLoader是在操作系统内核或用户应用程序运行之前运行的一段小程序。
通过这段小程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,为最终调用操作系统内核或用户应用程序准备好正确的环境。
15,大多数BootLoader都包含两种不同的操作模式:
“启动加载”模式和“下载”模式,这两种模式的区别仅对于开发人员才有意义。
从最终用户的角度看,BootLoader的作用是用来加载操作系统,并不存在所谓的启动加载模式与下载工作模式的区别。
启动加载(BootLoading)模式:
这种模式也称为“自主”(Autonomous)模式。
也即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。
这种模式是BootLoader的正常工作模式,在嵌入式产品发布的时候,BootLoader显然必须工作在这种模式下。
下载(Downloading)模式:
在这种模式下,目标机上的BootLoader将通过串口连接或网络连接等通信手段从主机下载文件,比如,下载内核映像和根文件系统映像等。
从主机下载的文件通常首先被BootLoader保存到目标机的RAM中,然后再被BootLoader写到目标机上的FLASH类固态存储设备中。
BootLoader的这种模式通常在第一次安装内核与根文件系统时被使用;此外,以后的系统更新也会使用BootLoader的这种工作模式。
工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口。
最常见的情况是,目标机上的BootLoader通过串口与主机之间进行文件传输,传输协议通常是xmodem/ymodem/zmodem协议中的一种。
但是,由于串口传输的速度是有限的,因此通过以太网连接并借助TFTP协议来下载文件是个更好的选择。
但是,在通过以太网连接和TFTP协议来下载文件时,因为主机方必须有一个软件用来的提供TFTP服务,所以操作相对复杂。
16,2BootLoader的启动过程从操作系统的角度看,BootLoader的总目标就是正确地调用内核来执行。
BootLoader的启动过程大多数分为阶段1和阶段2。
阶段1主要包含依赖于CPU体系结构的硬件初始化代码,而且通常都是用汇编语言来实现的,以达到短小精悍的目的。
这个阶段通常包括以下步骤:
(1)硬件设备初始化。
这是BootLoader开始就执行的操作,其目的是为阶段2的执行,以及随后内核的执行准备好基本的硬件环境。
(2)为加载BootLoader的阶段2准备RAM空间。
为了获得更快的执行速度,通常把阶段2加载到RAM空间来执行。
(3)拷贝BootLoader阶段2的代码到RAM空间中。
(4)设置好堆栈。
(5)跳转到阶段2的C程序入口点。
BootLoader的阶段2通常用C语言来实现,这样可以实现更复杂的功能,而且代码会具有更好的可读性和可移植性。
通常包括以下步骤:
(1)初始化本阶段要使用到的硬件设备。
(2)检测系统内存映射。
(3)将内核映像和根文件系统映像从Flash上读到RAM空间中。
(4)为内核设置启动参数。
(5)调用内核。
17,ARM指令集,18,3BootLoader代码分析下面对引导程序2410INIT.S进行分析,以加深对BootLoader的理解。
在第一阶段完成依赖于体系结构硬件初始化的代码,包括禁止看门狗、禁止中断、初始化各控制寄存器拷贝自身到RAM等。
IMPORTMainAREAInit,CODE,READONLYENTRYbResetHandlerResetHandlerldrr0,=WTCONldrr1,=0x0strr1,r0ldrr0,=INTMSKldrr1,=0xffffffffstrr1,r0ldrr0,=INTSUBMSKldrr1,=0x7ffstrr1,r0ldrr0,=LOCKTIMEldrr1,=0xffffffstrr1,r0ldrr0,=SMRDATAldrr1,=BWSCONaddr2,r0,#520ldrr3,r0,#4strr3,r1,#4cmpr2,r0bne%B0,blInitStacksldrr0,=HandleIRQldrr1,=IsrIRQstrr1,r0;拷贝自身代码到RAMldrr0,=|Image$RO$Limit|;ldrr1,=|Image$RW$Base|;ldrr3,=|Image$ZI$Base|cmpr0,r1beq%F21cmpr1,r3ldrccr2,r0,#4strccr2,r1,#4bcc%B12ldrr1,=|Image$ZI$Limit|movr2,#03cmpr3,r1strccr2,r3,#4bcc%B3blMainb.END,19,第二阶段通常用C语言实现,包括内存管理单元初始化、时钟设置、端口设置和串口初始化等。
voidIsr_Init(void)rINTMOD=0x0;/工作在IRQ模式rINTMSK=BIT_ALLMSK;/屏蔽中断rINTSUBMSK=BIT_SUB_ALLMSK;/屏蔽子中断voidMain(void)MMU_Init();/MMU初始化ChangeClockDivider(1,1);/设置时钟除法器-1:
2:
4ChangeMPllValue(0xa1,0x3,0x1);/时钟值FCLK=202.8MHzPort_Init();Isr_Init();Uart_Init(0,115200);Uart_Select(0);while
(1)Uart_Printf(nnSMDK2410Board(MCUS3C2410)ExampleProgramVer1.0(20020521)FCLK=%dHznn,FCLK);与一般的C语言程序一样,第二阶段程序从Main()函数开始。
因为所采用的S3C2410X处理器内含存储器管理单元MMU,所以首先需要进行存储器管理单元的初始化。
紧接着设置系统工作主时钟,若使用USB设备则USB时钟也需要做相应初始化。
其次对端口工作状态进行设定。
然后设定处理器工作模式,以及中断控制。
最后初始化串口,与宿主机建立联系,以利于显示调试信息。
启动成功后,可以执行主程序。
20,VIVI简介,VIVI是韩国Mizi公司开发的BootLoader,可用于ARM9处理器的引导。
VIVI利用串行通信为用户提供接口。
为连接VIVI,首先利用串口电缆连接宿主机和目标板,然后在主机上运行串口通信程序,并在目标板上正确设置VIVI以支持串口。
正确连接后,就可以由串口通信程序显示提示信息,提示信息的最后一行如下所示:
PressReturntostarttheLINUXnow,anyotherkeyforvivi.VIVI也有前面说过的两种工作模式,启动模式可以在一段时间后自行启动Linux内核,这是VIVI的默认方式。
出现上述信息后,如果按除回车键外的任意键,即可进入下载模式,出现“vivi”提示符。
在下载模式下,VIVI为用户提供了一个命令行接口,通过该接口可以使用VIVI提供的一些命令。
1load命令将二进制文件载入到Flash或者RAM,命令格式:
load|其中命令行参数描述装载位置,有flash和ram两种选项;参数或描述装载的地址,如果有提前定义的mtd分区信息,可以只输入分区名称,否则需要指定地址和大小;参数确定文件的传输协议,常采用的选项“x”用来指定采用xmodem协议。
例如:
viviloadflashkernelx,装载压缩映像文件zImage到flash存储器中,地址是kernel分区,并采用xmodem传输协议。
也可以指定地址和大小,例如:
viviloadflash0x800000xc0000x。
21,2part命令操作MTD分区信息,比如,显示、增加、删除、复位、保存MTD分区等。
partshow:
显示mtd分区信息。
partadd:
增加新的mtd分区,其中为新mtd分区名称,是mtd器件的偏移,表示mtd分区的大小,表示分区类型,可选项有JFFS2、LOCKED和BONFS。
partdel:
删除一个mtd分区。
partreset:
恢复mtd分区为默认值。
partsave:
在flash中永久保存参数值和分区信息。
3param命令用来设置或者察看参数。
例如:
改变“linuxcommandline”,使用viviparamsetlinux_cmd_lineyouwish.。
也可以改变引导程序启动的时间,使用viviparamsetboot_delay100000实现。
4boot命令用来引导存储在flash存储器或者ram中的linux内核。
命令格式:
boot|参数设定存储linux内核映像的位置,可选项有ram、nor和smc。
参数或描述存储内核的地址,如果有提前定义的mtd分区信息,可以只输入分区名称,否则需要指定地址和大小。
例如:
vivibootnor0x80000表示从flash存储器中读出linux内核,偏移是0x80000。
5flash命令存储器管理命令,例如:
flasherase|,表示擦除flash存储器。
22,VIVI的代码分析与移植,1arch此目录包括了所有VIVI支持的目标板的子目录,本书附带?
的代码中只包含S3C2410X。
2Documentation存放了许多文档,非常详细,主要是VIVI的使用指南。
3drivers其中包括了引导内核所需的MTD设备和串口驱动程序。
MTD目录下分maps、nand和nor三个目录,实现对NandFlash和NorFlash的读写控制。
Serial目录下的文件实现对串口的控制,并支持xmodem和ymodem协议。
4include头文件的公共目录,其中的S3C2410.h定义了处理器的一些寄存器,以及NANDFlash的一些寄存器等。
Platform/smdk2410.h定义了与目标板相关的资源配置参数,修改波特率、引导参数和物理内存映射等参数就可适用于自己的目标板。
5initinit目录,这个目录只有main.c和version.c两个文件。
与普通的C程序一样,VIVI将从main函数开始执行。
6lib一些平台公共的接口代码,比如,time.c里的udelay()和mdelay()。
7scripts主要在配置时用到,存放了配置所需的脚本文件,如Menuconfig和Configure文件,以方便对VIVI的配置。
23,VIVI的运行也可以分为两个阶段。
在第一阶段完成含有依赖于CPU体系结构硬件初始化的代码,利用汇编语言完成。
第二阶段是用C语言完成的。
在跳转进main()函数之前,利用汇编语言编写了一段trampoline程序作为阶段2可执行镜像的执行入口点。
之后可以在trampoline中用处理器的跳转指令进入main()函数中去执行。
当main()函数返回时,CPU就进行复位。
Trampoline程序的源代码如下:
ldrsp,DW_STACK_STARTmovfp,#0mova2,#0blmainmovpc,#FLASE_BASEmain()函数是在Flash中还是RAM中执行,与选择NandFlash还是NorFlash启动有关。
VIVI从NandFlash中启动时,在VIVI配置的时候定义宏CONFIG_S3C2410_NAND_BOOT以编译以下代码段。
#ifdefCONFIG_S3C2410_NAND_BOOTblcopy_myselfldrr1,=on_the_ramaddpc,r1,#0nopnop1:
b1binfiniteloopon_the_ram:
#endif该代码首先是将VIVI自身复制到RAM中,并跳转到RAM中去执行。
芯片复位时,NandFlash中最前面的4KB代码会被自动拷贝到芯片内部的4KBRAM,然后开始执行。
由于代码不能在NandFlash中执行,所以VIVI从NandFlash中启动的情况下,“blmain”是跳到RAM中的main函数。
24,VIVI的运行也可以分为两个阶段。
在第一阶段完成含有依赖于CPU体系结构硬件初始化的代
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第八