您的位置:首页 > 运维架构 > Linux

Linux移植课实验指导书

2011-07-21 16:43 405 查看
Linux移植课实验指导书

系统开发环境的安装和设置
实验中所需要的主要软件包
实验中涉及到的软件包主要有如下的一些:
arm-none-linux-gnueabi.tar.bz2:编译uboot,核心以及busybox所需要的工具链。
uboot-1.1.6_akae24xx.tar.gz:针对akae2410和akae2440开发板移植的uboot
kernel-2.6.27-android.tar.gz:支持akae2410和akae2440开发板的Linux核心,版本为2.6.27,并且内部也包括了google的android平台上需要的驱动
Linux-2.6.27.tar.gz:从Linux官方(www.kernel.org)下载的2.6.27的Linux核心,主要用于在其中加入对akae2410和akae2440开发板的支持的实验
testinit.c:用于测试小系统的小程序
busybox-1.1.3.tar.bz2和busybox_config:busybox和其配置文件

工具链的安装和设置
设目前的用户名为akaedu,在home目录下,主要的步骤为:
1.建立一个工作目录名称为Linux-porting,并将工具链的压缩包拷贝到该目录下
mkdir Linux-porting
2.将arm-none-linux-gnueabi.tar.bz2解压到该目录下
tar -jxvf arm-none-linux-gnueabi.tar.bz2 -C /home/akaedu/Linux-porting
3.设置工具链的路径,将工具链的可执行程序路径加到PATH环境变量中,注意这个设置在退出终端后就没有了,所以每次启动终端的时候都应该执行一次该命令(vim ~/.bashrc最后面添加如下命令)
export PATH=$PATH:/home/akaedu/Linux-porting/ arm-2008q3/bin/
4.测试工具链是否能正常工作,如果一切正常,应该能显示该工具链的相关信息
arm-none-linux-gnueabi-gcc -v

TFTP和 NFS的配置
TFTP的配置
1.首先需要安装tftpd的相关软件包
$ sudo apt-get install xinetd tftpd tftp
2.设置xinetd的tftp服务,具体为在/etc/xinetd.d/目录下创建一个tftp文件,并将如下的内容拷贝到该文件中
service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = nobody
server = /usr/sbin/in.tftpd
server_args = /tftpboot
disable = no
}
这里的server_args 后面的参数tftpboot为tftp的存取目录
3.创建tftp文件的存取目录tftpboot,并修改其目录的权限
$ sudo mkdir /tftpboot
$ sudo chmod -R 777 /tftpboot
$ sudo chown -R nobody /tftpboot

4.重启xinetd服务
$ sudo /etc/init.d/xinetd restart
$ sudo ifconfig eth0 192.168.1.21 up
xinetd 网络服务集

NFS的配置
1.首先需要安装nfs服务的相关软件包
sudo apt-get install nfs-kernel-server
2.创建nfs的存取目录rootfs,并修改其目录的权限
$ sudo mkdir /rootfs
$ sudo chmod -R 777 /rootfs
$ sudo chown -R nobody /rootfs
3.配置要输出的目录,可以在 /etc/exports 文件中添加该目录
/rootfs *(rw,no_root_squash,subtree_check,async)
4.重新启动nfs服务
sudo /etc/init.d/nfs-kernel-server restart
putty工具的安装和配置
putty是个简单实用的终端工具,使用上也比minicom要方便一点
首先需要安装该工具
sudo apt-get install putty
然后启动putty并进行相关的配置
putty &
注意connection type设置为serial,speed设置为115200,为该连接作一个命名,这里是akaedu-target,点击save进行保存。
用串口线将host和开发板连接,点击putty上的open,同时启动开发板,这个时候应该能进入vivi或u-boot的命令界面。见下图所示



u-boot试验
实验2-1:编译u-boot
这里生成的u-boot可以有两个不同的版本,一个是可以直接烧到开发板的NandFlash中并启动的版本,另外一个可以通过tftp加载到内存中运行的版本,主要用于u-boot的调试
1.首先解压uboot,之前应确认系统已经正常的安装了arm的工具链
tar -zxvf uboot-1.1.6_akae24xx.tar.gz
make distclean
不然出错 先要distclean
2.进入uboot目录
对于2440开发板,输入make akae2440_config
对于2410开发板,输入make akae2410_config

3.编译可运行于NandFlash上的uboot
首先确认include\configs目录下的akae2410.h或akae2440.h中的代码
#if 0
/* If we want to start u-boot from usb bootloader in NOR flash */
#define CONFIG_SKIP_RELOCATE_UBOOT 1
#define CONFIG_SKIP_LOWLEVEL_INIT 1
#else
/* If we want to start u-boot directly from within NAND flash */
#define CONFIG_S3C2410_NAND_BOOT 1
#define CONFIG_S3C2410_NAND_SKIP_BAD 1
#endif
如果#if为1,则以调试方式对uboot进行调试,否则代表可以将uboot烧到flash上启动,这里需要确认#if为0。这里的定义主要用于控制在cpu/arm920t/start.S中的代码在启动的时候是否从NANDflash上读取u-boot代码到内存中执行。
保存文件退出后,在命令行上输入make进行编译
$ make
编译完成后,在目录下应该能生成一个u-boot.bin,将该文件拷贝到tftp的导出目录中并重命名
$ sudo mv u-boot.bin /tftpboot/u-boot-nand.bin

4.编译可以运行在内存中可以进行调试的u-boot
首先确认include/configs目录下的akae2410.h或akae2440.h中的代码
#if 1
/* If we want to start u-boot from usb bootloader in NOR flash */
#define CONFIG_SKIP_RELOCATE_UBOOT 1
#define CONFIG_SKIP_LOWLEVEL_INIT 1
#else
/* If we want to start u-boot directly from within NAND flash */
#define CONFIG_S3C2410_NAND_BOOT 1
#define CONFIG_S3C2410_NAND_SKIP_BAD 1
#endif保存文件退出后,在命令行上输入make进行编译
将#if设置为1,保存后退出,然后在命令行输入
$ make clean
$ make TEXT_BASE=0x33000000
编译完成后在目录下同样会生成一个u-boot.bin的文件,将该文件拷贝到tftp的导出目录中并重命名
$ sudo mv u-boot.bin /tftpboot/u-boot-ram.bin
Jflash t= flash类型 d=延时
实验2-2:调试并烧写u-boot
将调试版本的u-boot加载到内存中运行
如果开发板上装有vivi的情况下可以利用vivi的load和go命令来进行,这里介绍的是利用u-boot的功能来加载u-boot的方法。首先应该确认主机上的tftp的配置已经完成,具体的配置可以参考1.3.1节的介绍。具体的步骤如下:
1.对uboot的ip进行配置,这里设主机的ip为192.168.1.21,分配给开发板的ip为192.168.1.22 ,则应该在u-boot的命令行上输入
setenv ipaddr 192.168.1.22
setenv netmask 255.255.255.0
setenv serverip 192.168.1.21
saveenv
可以利用printenv来查看所设置的env是否正确,整个过程如下图所示



2.确定主机和开发板之间的网线连接正确,这可以利用u-boot中的ping命令进行验证
ping 192.168.1.21
3.确定之前的u-boot-ram.bin拷贝到tftp的导出目录tftpboot中
sudo cp u-boot-ram.bin /tftpboot
4.利用tftp命令将u-boot-ram.bin加载到0x33000000上
tftpboot 0x33000000 u-boot-ram.bin
5.利用go命令跳转到加载的u-boot上执行
go 0x33000000
整个过程如下图所示



将uboot烧到开发板的Nandflash中
这里介绍通过u-boot的命令将u-boot烧写到NandFlash上的方法
1.首先通过tftp将u-boot的nand版本加载到内存,这里设为0x32000000
tftpboot 0x32000000 u-boot-nand.bin
2.在写入NandFlash前应先将Flash地址0x0上的内容擦除
nand erase 0x0 0x50000
3.将内存中的u-boot-nand.bin写到Flash中
nand write 0x32000000 0x0 0x50000
4.输入reset重启开发板
reset
整个过程如下图所示



实验2-3:利用实现的myboot命令启动Linux核心
1.按照实验3-1的描述编译并生成一个Linux核心,并将生成的核心zImage放到tftp的配置目录/rootfs中
sudo cp zImage /tftpboot
2.利用tftpboot命令将zImage通过网络加载到内存0x30008000
tftpboot 0x30008000 zImage
3.利用myboot命令将引导核心
myboot 0x30008000
出现Uncompressing Linux... done, booting the kernel. 错误
解决方法:MACHINE_START(AKAE2440, "AKAE2440")//此处标识修改

整个过程见下图所示



Linux核心移植试验
实验3-1:编译和配置Linux核心(24xx平台)
1.首先解压核心的压缩包kernel-2.6.27-android.tar.gz,编译的时候应确认系统已经正常的安装了arm的工具链
tar -zxvf kernel-2.6.27-android.tar.gz
cd kernel-2.6.27-android
2.导出核心编译的时候需要的两个环境变量ARCH和CROSS_COMPILE注意这个设置在退出终端后就没有了,所以每次启动终端的时候都应该执行一次该命令
export ARCH=arm //ARCH体系结构
export CROSS_COMPILE=arm-none-linux-gnueabi- //交叉编译器
3.如果不愿意每次都输入,可以直接修改核心的根目录下的Makefile,将第197行这两个环境变量修改为
ARCH = arm
CROSS_COMPILE = arm-none-linux-gnueabi-
4.在核心的目录下输入make menuconfig进行配置
make menuconfig
必须打开 Kernel Features ---> EABI
进入menuconfig后要先在systemtype->arm systemtype->samsung........
配置的时候应该要选中akae2410和akaed2440,如果一切正常的话选择应该是在System type-> S3C2410 Machines或System type-> S3C2440 Machines这两个选择项中,可以参考下图的选择,这里是AKAE2410



核心的配置过程中,其它选项要求
1.ext2文件系统支持
2.nfs文件系统的支持
3.ramdisk支持
4.initrd支持
5.ext2文件系统的支持在File systems选项中,如下图所示



NFS文件系统的支持也在File systems选项中,它的选项要更深一级,请注意一定要选中”Root file system on NFS”这一项。如下图所示



initrd的支持在General setup选项中,如下图所示



ramdisk的支持在 Device Drivers->Block devices选项中,如下图所示



目录arch/arm/configs/下有一个akae24xx_config是一个参考配置,可以直接拷贝到核心根目录下使用
配置的是哪一个就需要拷贝哪一个mini2440//cp arch/arm/configs/akae24xx_config ./.config

5.


6.输入make编译核心
make
输入make V=1可以查看编译核心的时候使用的编译选项等,对解决核心的编译问题有一定的帮助。
出现error: 'PCIMEM_BASE' undeclared (first use in this function) 此类错误
drivers/video/console/vgacon.c:292: error: `PCIMEM_BASE ' undeclared (first use in this function)
解决方法:
device drivers->Graphics support->Console display driver support-> [ ]VGA text console //由于电脑显卡需要PCI总线,所以要取消
出现错误ERROR: "ioport_map" [drivers/net/wireless/orinoco/spectrum_cs.ko] undefined!

解决方案:首先把wirless中大多数选项取消,如果出现如下错误
ERROR: "ioport_map" [drivers/char/tpm/tpm_atmel.ko] undefined!
在device drivers->character devices->取消 TPM hardware
实验3-2:在官方的Linux核心上加入对akae24xx的支持
akae2410平台
1.首先在/arch/arm/mach-s2c2410目录下编写mach-akae2410.c,具体的模式可以参考kernel-2.6.27-android下的代码,请按课程中讲解的内容务必领会其中各个代码的具体含义
2.修改时钟频率:
static void __init smdk2440_map_io(void)

{

s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));

s3c24xx_init_clocks(12000000);

s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));

}

MACHINE_START(AKAE2440, "AKAE2440")//此处标识修改

/* Maintainer: Ben Dooks <ben@fluff.org> */

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100,

.init_irq = s3c24xx_init_irq,

.map_io = smdk2440_map_io,

.init_machine = smdk2440_machine_init,

.timer = &s3c24xx_timer,

MACHINE_END

3.修改Kconfig和Makefile,在Kconfig中加入
config MACH_AKAE2410
bool "AKAE2410"
select CPU_S3C2410
help
Say Y here if you are using the akaedu 2410 board
在Makefile中加入
obj-$(CONFIG_MACH_AKAE2410) += mach-akae2410.o
可以参考kernel-2.6.27-android目录下的相关文件
4.在/arch/arm/tools的mach-types文件中的最后一行加入对AKAE2410的支持
akae2410 MACH_AKAE2410 AKAE2410 1874
5.按照实验3-1的说明对核心进行配置,如果正常的话,在核心的菜单中应该能看到实验3-1的图中的选项,选中aka2410。核心的配置同样要保证对ext2文件系统,ramdisk和initrd的支持

akae2440平台
基本的过程和akae2410平台的一致,修改和添加的文件应该在/arch/arm/mach-s2c2440目录下进行,在/arch/arm/tools的mach-types文件中的最后一行加入对AKAE2440的支持为:
akae2440 MACH_AKAE2440 AKAE2440 1875

编译核心
可以按照实验3-1的说明对核心进行编译,编译后生成的zImage同样也放到tftp的导出目录tftpboot下,然后利用烧写在板子上的u-boot按照实验2-3介绍的方法对这个核心进行引导和测试。

实验3-3:生成ext2文件系统
1.首先利用dd命令产生一个image文件,注意大小不要超过6M
sudo dd if=/dev/zero of=ext2fs.img bs=1k count=6144
dd 是 Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
2.然后将该image和环回设备连接在一起
sudo losetup /dev/loop0 ext2fs.img
losetup用来将loop device与档案或block device联结、分离.以及查询loop device目前的状况
3.利用mke2fs对该image进行格式化
sudo mke2fs -m 0 /dev/loop0
mke2fs建立ext2文件系统
4.新建一个目录,并将该目录挂载到和image连接的环回设备上
mkdir temp//操作temp都是在读写ext2fs.img
sudo mount /dev/loop0 temp/
5.编写想要核心运行的第一个程序
程序为
#include <stdio.h>

int main(int argc, char * argv[])
{
int count = 0;
while(1){
printf("hello, my frist program, count=%d\n", count++);
sleep(1);
}
}

6.以静态方式编译该程序
arm-none-linux-gnueabi-gcc -march=armv4t -mtune=arm9tdmi -msoft-float -static -o testinit testmain.c //static静态链接
7.将编译好的文件放在该temp目录中,这里也就是这个testinit
sudo cp testinit temp/
8.在temp目录中创建目录dev,并创建必要的设备文件
sudo mkdir dev
建立了DEV目录后,把如下东西放到DEV目录下
sudo mknod console c 5 1
sudo mknod ttySAC0 c 204 64
sudo mknod ttySAC1 c 204 65
sudo mknod ttyS0 c 4 64
sudo mknod ttyS1 c 4 65
sudo mknod tty1 c 4 1
sudo mknod mtdblock0 b 31 0
sudo mknod mtdblock1 b 31 1
sudo mknod mtdblock2 b 31 2
sudo mknod mtdblock3 b 31 3
在此写一个shell 通过 sh 来执行
在temp文件中的操作其实就是在ext2fs.img
9.umount该temp目录,并解除和image之间的环回连接
sudo umount temp/
sudo losetup -d /dev/loop0
这个时候就得到了一个最小的文件系统,该文件系统中唯一的程序就是前面编写好的testinit程序,后面的实验中将让核心在初始化的时候执行的第一个程序就是它。

实验3-4:利用ramdisk实现该文件系统的挂载
1.在uboot中添加三个环境变量bootmode,init和rdsize,并分别将其设置为ramdisk,testinit和0x800000
setenv bootmode ramdisk //用内存模拟磁盘(文件系统)
setenv init /testinit //加载的程序
setenv rdsize 0x800000 //加载大小
saveenv
2.将前面实验中得到的ext2fs.img拷贝到tftp的导出目录tftpboot下
sudo cp ext2fs.img /tftpboot
3.利用tftpboot命令将核心和ext2fs.img加载到内存的0x30008000和0x30800000这两个地方
tftpboot 0x30008000 zImage
tftpboot 0x30800000 ext2fs.img
4.利用myboot程序引导核心, 这个时候应该可以看到系统的第一个进程,也就是testinit打印的字符
myboot 0x30008000
文件系统找不到是u-boot传递参数不对 在arch/arm/plat-s3c24xx下面的common-smdk.c作mtd_partition的修改
文件系统必须用*
整个过程如下图所示



实验3-5:编译和制作busybox小系统
1.将前面的ext2fs.img重新mount到temp目录上
sudo mount -o loop ext2fs.img temp/
2.将busybox解压
tar –jxvf busybox-1.1.3.tar.bz2
3.将busybox_config拷贝到解开的目录中并命名为.config
cp busybox_config busybox-1.1.3/.config
4.对busybox进行配置
cd busybox-1.1.3
make menuconfig
配置的时候有如下的几个要点:
/home/akaedu/linux-porting/arm-2010q1/bin

注意将安装目录设置为temp目录,必须是绝对路径,这个设置Busybox Settings-> Installation Options中
Busybox Settings-> Build Options 中的设置为
Build BusyBox as a static binary选上
Cross Compiler prefix应该设置为arm-none-linux-gnueabi-
Any extra CFLAGS options for the compiler设置为-march=armv4t -mtune=arm9tdmi -msoft-float
如下图所示
可以参考busybox_config中的配置
5.完成后进行对busybox进行安装,完成后在temp目录下应该可以看到几个目录和相应的程序
make defconfig//默认设置
sudo make install
6.完成后将temp目录进行umount
sudo umount temp

实验3-6:引导busybox小系统
1.前面实验中得到的ext2fs.img拷贝到tftp的导出目录tftpboot下
sudo cp ext2fs.img /tftpboot
2.修改先前设置的uboot参数init将其修改为/bin/sh
setenv init /bin/sh
saveenv
3.利用tftpboot命令将核心和ext2fs.img加载到内存的0x30008000和0x30800000这两个地方
tftpboot 0x30008000 zImage
tftpboot 0x30800000 ext2fs.img
4.利用myboot加载Linux核心,加载成功后可以看到系统的标准shell界面

实验3-7:在核心中添加网络的功能,实现nfs方式的挂载
核心中的代码已经有对cs8900芯片的支持,只需要对driver/net目录下的cs89x0.c代码作一定的修改就可以支持我们的开发板。可以使用diff命令将kernel-2.6.27-android.tar.gz和标准核心Linux-2.6.27.tar.gz中的cs89x0.c作一个对比,可以查看该文件的差异。理解这些差异,并将这些修改添加到标准核心Linux-2.6.27.tar.gz中并编译。
查看挂载是否成功用 :sudo mount -t nfs 192.168.1.21:/rootfs /home/akaedu/tnt
完成后可以通过nfs方式对Linux小系统进行挂载,主要的过程如下:
1.参考1.3.2节中的方法对NFS进行配置
2.按照实验3-5的方法对busybox进行编译和配置,只是注意在设置安装路径的时候应该设置成NFS的导出目录/rootfs
3.按照实验3-5的方法对busybox进行安装
sudo make install
在rootsf目录下要建立/dev文件
mknod console c 5 1

4.启动开发板,设置如下的一些环境变量
setenv bootmode nfs
setenv gateway 192.168.1.21
setenv nfsroot /rootfs//nfsroot 是NFS是在那里
//root 是文件系统的根 从何处开始
//root = /dev/nfs //这只是一个标识不是实际存在
saveenv
5.利用tftpboot命令将核心加载到内存的0x30008000处,并使用myboot引导核心
tftpboot 0x30008000 zImage
myboot 0x30008000

实验3-8:将核心烧写到Flash中,实现系统自启动
1.重新编译一个nand版本的u-boot,注意CONFIG_BOOTCOMMAND的设置为:
#define CONFIG_BOOTCOMMAND \
"nand read 0x30008000 kernel 0x00200000; myboot 0x30008000"
这是在u-boot启动的时候自动会执行的命令序列,以分号隔开。这里也就是将核心从kernel分区中读出后通过myboot命令进行引导
2.将生成的u-boot按照实验2-2的方法烧到开发板上并重新启动开发板
3.输入mtdparts default设置默认的分区,并保存环境变量
mtdparts default
这个时候输入printenv应该能看见默认的分区
saveenv
4.将该核心通过tftpboot命令加载到内存的0x32000000的位置
tftpboot 0x32000000 zImage
5.将加载的核心烧到开发板的分区kernel上
nand erase kernel 0x200000 //flash必须先擦后写
nand write 0x32000000 kernel 0x200000
6.重新启动开发板,等待5秒后系统就能自动启动起来

实验3-9: 制作一个通过init进程启动的小系统
1.在rootfs目录下建立一个目录名为etc,并在该目录下创建目录init.d
mkdir /rootfs/etc
mkdir /rootfs/etc/init.d
2.在目录etc下创建文件inittab,内容为:
::sysinit:/etc/init.d/rcS

ttySAC0::respawn:-/bin/sh
tty1::respawn:-/bin/sh
tty2::askfirst:-/bin/sh

::ctrlaltdel:/bin/umount -a -r

3.在目录init.d下创建文件rcS,这是一个shell脚本,内容为:
#! /bin/sh

# Set the path
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

# Set the hostname.
hostname -F /etc/HOSTNAME

# mount proc and devpts filesystem
/bin/mount -a
#mount -o remount,rw /dev/root /
#mount -n / -o rw,remount
mount -t proc /proc /proc
mount -t ramfs none /tmp
#mount /dev/pts

if [ ! -f /etc/HOSTNAME ]; then
echo ${HOSTNAME} > /etc/HOSTNAME
fi

4.起动开发板,设置环境变量init为/bin/init
5.设置环境变量bootmode为nfs
setenv bootmode nfs
setenv init /bin/init
6.通过tftpboot加载核心,利用myboot引导该核心并挂载nfs文件系统
tftpboot 0x30008000 zImage
myboot 0x30008000
7.可以利用实验3-8的方法将修改烧到flash上,完成系统的自启动
sudo ln -s busybox init
//必须链接

下面是编译内核驱动要用到的:可以先不管
#!不是注释
mount -a
mount -t proc /proc /proc

将核心烧写到Flash中,实现系统自启动
1.首先按照实验3-3和3-5的方法生成一个ext2fs.img的ext2文件系统image,内部包含busybox的小系统,注意大小不要超过16M,生成image的命令如下:
sudo dd if=/dev/zero of=ext2fs.img bs=1k count=16384
2.根据前面介绍的方法在这个ext2fs.img中写入busybox和etc目录下的相关内容
3.将前面生成的ext2fs.img文件系统image 通过tftpboot命令加载到内存的0x30800000的位置
tftpboot 0x30800000 ext2fs.img
4.将加载的ext2fs.img文件系统烧到开发板的分区ext2上
nand write 0x30800000 ext2 0x01000000
5.设置引导模式为nand
setenv bootmode nand
6.重新启动开发板,等待5秒后系统就能自动启动起来
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: