blogernice

导航

嵌入式linux开发流程

Minicom:Linux下的终端程序,用于通过串口进行通信,在嵌入式Linux系统中,可以用于主机与目标系统通信,实现串口控制台的功能。

DHCP: 动态主机配置协议。运行实现该协议的服务的主机,通过对客户发起的DHCP请求进行应答,可以动态的配置客户机的IP地址等网络信息。

TFTP: 一种FTP文件传输协议。由于实现相对简单,常用于嵌入式系统获取版本信息。在嵌入式Linux中,用于目标板从本机获取Linux内核以及其他文件映像。

NFS:网络文件系统。运行NFS客户端的主机,可以从运行NFS服务端的主机安装网络文件系统,对于客户机来说,使用该文件系统与使用本地文件系统没有任何差别。NFS最常用于基于嵌入式Linux的应用开发的调试阶段。

 

目标系统单板集成阶段

作为一个嵌入式Linux系统,最终需要脱离开发环境独立运行。因此,必须为目标系统准备独立的文件系统,并配置相应的启动脚本,服务程序等等。

动态主机配置协议(DHCP)是用来自动给客户机器分配 TCP/IP 信息的网络协议。在开发的过程中,目标系统并没有自己的静态IP地址,它是在启动时向DHCP服务器申请,因此需要在主机上配置DHCP服务,以便在目标系统请求IP时,动态为它分配IP地址。 

DHCP服务的配置文件为/etc/dhcpd.conf,通过修改该文件进行配置。

1.添加如下的配置信息,生成一个配置示例:

subnet 192.9.200.0 netmask 255.255.255.0{

default-lease-time 1209600; # two weeks

max-lease-time 31557600; # one year

group{

host target1{

hardware ethernet 00:01:EC:00:00:00;

fixed-address 192.9.200.145;

option root-path ”/ELDK/…/target”;

}

    }

}

 

2.在该配置示例的基础上做如下修改:

将“subnet 192.9.200.145”中的子网地址(192.9.200.145)替换为实际的主机子网地址;

1) 在“host target1”一行中,“target1”为目标板的名称,将它替换为你希望的名称;

2) 在“hardware ethernet 00:01:EC:00:00:00”一行中,是设置目标板的MAC地址,将其中的MAC地址替换为实际目标板的地址;

3) 在“fixed-address 192.9.200.145”一行中,是设置将要为该目标板分配的IP地址,把它替换为你想要为目标板分配的实际IP地址;

4) 在“option root-path “/ELDK/…/target””一行中,是设置nfs输出的文件系统目录,将它替换为实际要输出的文件系统目录。

3.重新启动dhcp服务,使用如下命令:

# /etc/rc.d/init.d/dhcpd start

4.为避免每次启动主机都要手工启动dhcp服务,使用如下命令使得dhcp服务在每次系统启动时都默认执行:

# chkconfig dhcpd on

 

配置TFTP

在目标系统的开发过程中,Linux内核是从主机下载到目标系统上解压并运行的,因此主机必须提供这种文件传输服务。Tftp是一种简单的文件传输协议,多用于嵌入系统应用中,因此主机需要配置tftp服务,供下载内核时使用。

1. Tftp服务的配置文件为/etc/xinetd.d/tftp,其内容如下:

service tftp

{

socket-type=dgram

protocol=udp

wait=yes

user=root

server=/usr/sbin/in.tftpd

server-args=-s /tftpboot

disable=no

}

2.修改配置参数:

Tftp配置参数比较简单,只需将server-args的参数配置为图中所示的“-s /tftpboot” ,其他使用默认配置即可。

srver-args参数是一个目录,该目录中包含要下载到目标系统中去的linux内核映像文件。

3.在主机上创建/tftp目录,以供存放内核:

使用如下命令创建/tftp目录:

# mkdir /tftp

这样,每次在重新编译好用于目标系统的内核后,拷贝到该目录下即可。

4.重新启动tftp服务:

# killall-USRI xinetd

5.为避免每次启动主机都要手工启动tftp服务,使用如下命令使得tftp服务在每次系统启动时都默认执行:

# chkconfig tftp on

 

配置NFS服务

网络文件系统(NFS)是一种在网络上的机器间共享文件的方法,在开发的过程中,目标系统没有足够的本地存储设备供使用,它可以通过主机提供的NFS服务,使用在主机上的文件系统,就如同位于本地硬盘驱动器上一样。

1.修改NFS配置文件:

NFS服务的配置文件为/etc/exports,其内容如下:

<nfs-export-dir> *(rw,no-root-squash,no-all-squash)

其中,<nfs-export-dir>表示NFS向目标提供的文件系统目录,将它替换成具体的输出目录。例如:

      /ELDK/hardhat/devkit/ppc/8xx/target是ppc/8xx系列目标板缺省安装的文件系统;也可以是用户自己为目标板裁减的文件系统目录。

同时可以有输出多个目录,方便开发调试。

2.重新启动NFS服务:

# /etc/rc/.d/init.d/nfs start。

确认NFS守护进程正在运行。

3.为避免每次启动主机都要手工启动nfs服务,使用如下命令使得nfs服务在每次系统启动时都默认执行:

# chkconfig nfs on

 

配置内核

# cd  / //进入根目录

# mkdir /develop //建立开发目录

# cp  -r   /ELDK1.0/target/kernel_src/linux  /develop  //拷贝内核源代码到develop目录

# cd /develop/linux

# make menuconfig

编译内核

内核配置结束后,需要对内核源代码进行编译,得到目标系统运行所需的linux内核映象文件。

编译内核的步骤为:

1) 进入linux源代码目录下:

# cd /develop/linux

2) 如果以前曾经编译过内核,则清除所有旧的目标文件,如果没有跳到第3步:

# make clean

3) 找出每个源文件的依赖性,并把它引入各个 Makefile 中:

# make dep

4) 编译内核,生成内核映像文件:

# make ARCH=<arch> CROSS_COMPILE=<cross_compile> bzImage

此处的<arch>和<cross_compile>根据目标系统的实际体系架构填写。例如:如果是目标系统是PowerPC架构,命令为:

# make ARCH=ppc CORSS_COMPILE=powerpc-linux- bzImage

完成上述步骤后,内核映像文件生成,它的位置在/develop/linux/arch/<ARCH>/boot/bzImage

 

目标系统的根文件系统

与其它操作系统不同,对嵌入式Linux系统而言,文件系统是必须的。我们必须为目标系统配置文件系统,Linux才能正常启动。才能进行正常的调试和测试。

一 般而言,由于开发阶段我们需要目标系统的文件系统可以任意修改,而且可以包含更多的程序以便于我们的调试与测试;而在产 品实际运行阶段,我们希望的是目标系统使用尽可能少的存储空间,使用尽可能少的内存。有更快的速度。针对这两种不同的需求,在嵌入式Linux的开发当 中,针对开发阶段与实际运行阶段。我们一般使用不同的目标文件系统配置:

a.开发阶段的目标文件系统

为了满足开发阶段对文件操作方便,文件系统容量需求比较大的情况,在开发阶段,我们一般使用NFS(网络文件系统)作为目标文件系统的根文件系统。

目标系统所使用的NFS根文件系统由开发主机上运行的NFS服务所提供。由于运行在开发主机上,主机使用硬盘作为存储空间,因此目标系统对存储空间的需求几乎可以不受限制的得到满足。

b.实际产品单板中的文件系统

单板中一般配置Flash作为存储介质。嵌入式Linux系统需要将内核、应用程序以及需要的辅助工具(如登录Shell、网络服务等)存放在有限的flash中。

为 了做到在小容量介质中驻留Linux操作系统和应用程序。目前嵌入式Linux领域广泛使用busybox构建一个最小 的有可操作Shell的板上Linux系统。Busybox是一个可以自由获取的免费软件。它将Linux常用的命令集成在一个可执行文件中,由于采用多 调用(MultiCall)的方式。Busybox能够做到非常小的体积。

如果单板系统中需要使用函数库,则可 以考虑使用uclibc。Uclibc同样是可以免费获取的软件,它通过重写C语言的 函数库,以达到减小函数库所占用存储空间的目的。与标准的GNU C函数库相比,uclibc能够做到显著节省存储空间。一般而言,只需要使用 uclibc函数库重新编译应用程序,应用程序就可以在uclibc环境下执行。

根据单板应用程序的复杂程度以及最终的占用空间对比。单板可以采用如下两种方式之一来构建系统:

静态连接的busybox + 静态连接的应用程序;

uclibc + 动态连接的busybox + 动态连接的应用程序.

 

1.目标机的启动(目标机是指用于仿真开发板的PC):

容量小于1Mbyte的内核的启动,在Linux平台下,使用命令:dd if=bzImage of=/dev/fd0 就可以制作所需要的启动软盘。

1.1容量大于1Mbyte的内核的启动

由 于Linux操作系统启动机制的限制,对于大于1Mbyte的内核,无法由代码自身自行启动,而是需要借助启动装载器 (Boot Loader)来启动。对于软盘而言,最适用的启动装载器就是SYSLINUX。制作使用SYSLINUX启动Linux内核的软盘的步骤如 下。

格式化软盘,可以使用Shell命令:

mkfs –t msdos /dev/fd0

拷贝编译的Linux内核到软盘,使用如下Shell命令:

mount /dev/fd0 /mnt/floppy

cp bzImage /mnt/floppy

编辑软盘上的syslinux.cfg,配置启动参数,该文件缺省内容如下:

default linux(默认启动Linux)

prompt 1(允许启动提示)

timeout 600(设定超时时限为600);

label linux(此处增加一个名为Linux的启动选项)

kernel bzImage(指明内核文件名为bzImage)

append root=/dev/nfs,rw ip=bootp(内核命令行参数)。

卸载软盘,使用Shell命令:

umount /mnt/floppy

使该软盘可以启动,使用Shell命令:

syslinux /dev/fd0

 

1.2环境搭建

由于目标机在内核启动阶段需要从开发主机处获取自身的网络配置参数,并且最终从开发主机处安装NFS根文件系统并正常启动到shell提示符。所以首先要保证开发主机与目标机之间有正常的网络连接。

由于目标机用户获取网络配置信息的协议Bootp是运行在MAC层的。因此需要注意让目标机与开发主机位于同一个二层网络上,因为Bootp协议无法穿透有些IP路由器等网络设备。

启动开发主机并运行相应服务

DHCP服务,该服务为目标机自动配置IP地址、网关、NFS服务器地址、NFS服务目录等信息。

NFS服务,该服务为目标机提供运行所需要的根文件系统。

1.3运行应用程序

通过一个简单的“hello world”程序的编写和运行,使用户了解如何开发在主机开发应用程序,并使其运行在目标系统上。以下的c程序例子是基于PowerPC目标系统,使用ppc-8xx-的交叉开发工具链。步骤如下:

1. 在主机上,编写“hello world”程序,如下:

# include<stdio.h>

int main(int argc,char**argv){

printf(“hello world!\n”);

return 0;

}

2. 使用交叉编译器编译可执行程序:

# ppc-8xx-gcc -o  hello  hello.c

3. 把可执行程序拷贝到主机向目标系统输出的NFS文件系统的目录中:

# cp hello  /ELDK1.0/target/arch/ppc/target_fs

4. 在目标系统上运行hello程序:

#./hello

Hello world

 

2.目标板的启动

2.1制作BOOTROM

与目标机环境不同,由于实际的单板上并没有现存的启动程序,因此启动目标板的第一步,就是要制作启动并初始化目标板的BOOTROM程序。

2.1.1移植、调试Boot程序

我们使用移植后的U-Boot作为嵌入式Linux的Boot程序。U-Boot是一个可以从因特网上自由下载的开发源代码的免费软件,它可以支持多种CPU系列的目标系统的启动,包括PowerPC、ARM 、X86等。

2.1.2产生烧写BOOTROM所需的二进制文件

由于各种单板上BOOTROM配置情况的差异,包括BOOTROM容量、BOOTROM地址配置。以及不同CPU架构的单板的启动机制的差别。需要我们对编译生成的二进制文件进行相应的处理,才能正确的烧写到芯片中。需要特别注意以下内容:

CPU上电后开始执行的地址,必须确保相应的跳转指令位于此处,并正确的跳转到程序的入口。

由于文件烧写软件的限制。为了将所有的代码都能够烧写到芯片中,对于上电时候执行的代码位于地址高端的CPU架构的单板,需要进行正确的填充,以确保启动芯片与所配置的地址空间对应的物理位置上有相应的内容。

2.2烧写BOOTROM

制作好BOOTROM的二进制文件以后,就需要把它烧写的目标板所使用的BOOTROM芯片中。烧写BOOTROM芯片一般用烧片器进行,启动烧片器,选择正确的BOOTROM芯片类型,装入上一步中制作好的二进制文件,就可以进行烧写了。

posted on 2018-10-30 16:47  blogernice  阅读(1922)  评论(0编辑  收藏  举报