Linux移植课实验指导书

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秒后系统就能自动启动起来


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值