arm-linux移植手记(二)bootloader移植(下)

    书接上回。。。。。。。。哈哈。。。。。。。
    最开始我没有增加DM9000驱动,本想着用supervivi直接烧写内核就可以了,只要将内核的位置告诉u-boot,它自己复制到ram中引导即可,即使它自己不会,那我用nand read自己复制也行啊,可是试了很多次都不成功,只好改用nfs下载保存到nand flash上,没想到不但内核启动了,连文件系统跟着都能用了。。。。。。。。。。。。话说回来,还是要先看看u-boot的基本命令是怎么用的。

    一、添加内核引导  参考《u-boot-2009.08在mini2440上的移植(六)---增加引导内核功能  》(行数不够准确哦~)

【1】机器码的确定
通常,在u-boot和kernel中都会有一个机器码(即:MACH_TYPE),只有这两个机器码一致时才能引导内核,否则就会出现如下mach的错误信息或者死机。
打开board/samsung/mini2440/mini2440.c,定位到124行附近,修改如下:

#if defined(CONFIG_S3C2410)
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
#endif
#if defined(CONFIG_S3C2440)
/* arch number of S3C2440-Board */
 gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif

   (2)修改u-boot中内核引导参数:
打开/include/configs/mini2440.h,定位到60行附近,修改如下:
#define CONFIG_BOOTDELAY 3


//boot kernel
#define CONFIG_SETUP_MEMORY_TAGS     1 //如果没有定义这个参数,则uboot参数必须加入men=内存大小
#define CONFIG_INITRD_TAG            1
#define CONFIG_CMDLINE_TAG           1 //设置bootargs出入内核必须
#define CONFIG_BOOTARGS "noinitrd console=ttySAC0,115200  init=/linuxrc mem=64M \
root=/dev/mtdblock3 rw rootfstype=yaffs \
ip=10.1.0.129:10.1.0.128:10.1.0.1:255.255.255.0::eth0:off"
/*#define CONFIG_BOOTARGS "root=ramfs devfs=mount console=ttySA0,9600" */
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b 
#define CONFIG_NETMASK          255.255.255.0
#define CONFIG_IPADDR 192.168.0.223
#define CONFIG_SERVERIP 192.168.0.224
#define CONFIG_GATEWAYIP 192.168.0.1
#define CONFIG_OVERWRITE_ETHADDR_ONCE
/*#define CONFIG_BOOTFILE "elinos-lart" */

#define CONFIG_BOOTCOMMAND "nand read 0x30008000 0x00060000 0x500000;bootm \ 0x30008000"//"tftp; bootm" 


#if defined(CONFIG_CMD_KGDB)

    还是把上面的IP统一了吧,这里复制我的才发现这个问题,难怪第一次不能用,还得配ip,原来这里的不同。

    (3)制作能被u-boot直接引导的内核uImage
    通常,kernel的启动需要u-boot提供一些参数信息,比如ramdisk在RAM中的地址。经过编译后的u-boot在根目录下的tools目录中,会有个叫做mkimage的工具,他可以给zImage添加一个header,也就是说使得通常我们编译的内核zImage添加一个数据头信息部分,我们把添加头后的image通常叫uImage,uImage是可以被u-boot直接引导的内核镜像。
mkimage工具的使用介绍如下:
使用: 中括号括起来的是可选的
mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
选项:
-A:set architecture to 'arch'       //用于指定CPU类型,比如ARM
-O:set operating system to 'os'     //用于指定操作系统,比如Linux
-T:set image type to 'type'         //用于指定image类型,比如Kernel
-C:set compression type 'comp'      //指定压缩类型
-a:set load address to 'addr' (hex) //指定image的载入地址
-e:set entry point to 'ep' (hex)    //内核的入口地址,一般为image的载入地址+0x40(信息头的大小)
-n:set image name to 'name'         //image在头结构中的命名
-d:use image data from 'datafile'   //无头信息的image文件名
-x:set XIP (execute in place)       //设置执行位置
 先将u-boot下的tools中的mkimage复制到主机的/usr/local/bin目录下,这样就可以在主机的任何目录下使用该工具了。现在我们进入kernel生成目录(一般是arch/arm/boot目录),然后执行如下命令,就会在该目录下生成一个uImage.img的镜像文件,把他复制到tftp目录下,这就是我们所说的uImage。打开终端,现操作如下:

# mkimage -n 'mini2440_linux' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage uImage

更改用户执行权限(我自己试的不改权限也可以)

# chmod a+x uImage

(4)nfs下载及写入到nand中如下(超级终端上复制的信息):

SMDK2410 # ping 192.168.0.224
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:12:12:12:12:1a
operating at unknown: 0 mode
Using dm9000 device
host 192.168.0.224 is alive
SMDK2410 # nfs 0x30008000 192.168.0.224:/uImage
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:12:12:12:12:1a
operating at unknown: 0 mode
Using dm9000 device
File transfer via NFS from server 192.168.0.224; our IP address is 192.168.0.223

Filename '/uImage'.
Load address: 0x30008000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ################################################T T T T T *** ERROR: Ca
nnot umount
还是老是有 *** ERROR: Cannot umount,不过不影响使用。


SMDK2410 # nand erase 0x60000 500000

NAND erase: device 0 offset 0x60000, size 0x500000
Erasing at 0x540000 -- 100% complete.
OK
SMDK2410 # nand write 0x30008000 0x60000 500000

NAND write: device 0 offset 0x60000, size 0x500000
 5242880 bytes written: OK
SMDK2410 # nand read 30008000 0x60000 500000

NAND read: device 0 offset 0x60000, size 0x500000
 5242880 bytes read: OK

    二、补充下我的引导位置的设定
    我的nand flash中在0x40000-0x60000存u-boot环境变量,0x60000-0x560000存放内核文件,而后是yaffs2根文件系统,这样安排主要是看到原厂的启动信息里面是这样分配的:
启动开头有这样一句
Copy linux kernel from 0x00060000 to 0x30008000, size = 0x00500000 ... done
过程中还有这样一句:
Creating 5 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x000000000000-0x000000040000 : "supervivi"
0x000000040000-0x000000060000 : "param"
0x000000060000-0x000000560000 : "Kernel"
0x000000560000-0x000040560000 : "root"
因此就这么用了。这里有个疑问是mtd分区的话,为什么文件系统supervivi下载可以用,而内核下载进去了却老是不能用。
看看直接从nand flash启动:
    三、补充点问题解决
    有点小问题:
(1)测试编译环境
make mini2440_config
Makefile:3054: *** 遗漏分隔符 。 停止。
缺少tab键

(2)stage1部分的修改  寄存器、时钟设置
错误:
s3c24x0_rtc.c:33:34: error: asm/arch/s3c24x0_cpu.h: No such file or directory
修改正确的目录位置。
(3)可以使用nand read命令后,我不停的把uImage下载到ram中,但是每次都是
NAND read: device 0 offset 0x60000, size 0x500000
NAND read from offset 60000 failed -74
甚至查到failed -74这个错误码表示 非数据 的意思,而且也找到了错误位置,想继续深入,结果感觉可能是supervivi烧写可能加了什么,因此想到用nfs下载试试。
在nand flash启动时有如下信息:
NAND read: device 0 offset 0x60000, size 0x500000
NAND read from offset 60000 failed -74
 5242880 bytes read: ERROR
## Booting kernel from Legacy Image at 30008000 ...
   Image Name:   mini2440_linux
   Created:      2011-10-16   6:40:28 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2574208 Bytes = 2.5 MiB
   Load Address: 30008000
   Entry Point:  30008040
   Verifying Checksum ... Bad Data CRC
ERROR: can't get kernel image!

    这也还是那个问题,网上还有说是可能提供的大小有问题,我这里确定应该不是,因为内核才2.5MB。。。

    最后一个问题是在前文构建的gcc下编译我们的u-boot。我把在Fedora下的u-boot文件夹直接打包,复制到debian下,编译,由于没有记录,这里只能是回忆了:

问题1:

    首先是编译命令的问题,前面在makefile中设置交叉编译环境为arm-linux-gcc,原来生成的gcc是arm-none-linux-gnueabi-gcc,即使在makefile中改成目前的名字还是不能用。那么仿照原厂gcc的出来方法,采用ln -s为gcc、as等常用的建立链接,如

#ln -s arm-none-linux-gnueabi-as arm-linux-as

对于gcc和g++,可以和原厂一样,复制shell脚本,增加-march=armv4t

问题2:可能会出现某些文件找不到的情况,提示的目录是在fedora下的。

    那应该是没有清理干净,可以先make clean,在make distclean

问题3:

    开始编译了,走了会,冒出个--fix-v4bx not recognition,好像是这个来着,也碰到的人可以给我留言,我更正一下,不想再来次了。是as的问题。产生这个的原因是自己编译的gcc使用了EABI,但是一般支持的指令集不是我们使用的armv4的,虽然gcc修正了下,但是binutils工具集里的修正这里没有跟上(我的版本是2.18),需要补丁,想想干脆重新下了个binutils-2.20.1.tar.bz2,解压编译(单独编译它就可以了)安装。

问题4:

    终于编译成功了,但是下载到板子上就是不运行;想想我的gcc把内核都可以没有的编译了,怎么这个不行了。在板厂官网上的解释是必须对应编译器版本,以为自己白折腾了,自己对比原厂gcc和我的gcc配置,又不知道从哪来搜得,发现只要在第二次编译gcc时,配置中指定上--with-arch=armv4t --with-cpu=arm920t --with-tune=arm920t,相当于我就针对这类cpu、指令集了。

    顺利通过,贴个启动信息:

U-Boot 2010.06 (Oct 17 2011 - 21:01:36)


DRAM:  64 MiB
Flash: 512 KiB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0


NAND read: device 0 offset 0x60000, size 0x500000
 5242880 bytes read: OK
## Booting kernel from Legacy Image at 30008000 ...
   Image Name:   mini2440_linux
   Created:      2011-10-20   6:50:28 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2496644 Bytes = 2.4 MiB
   Load Address: 30008000
   Entry Point:  30008040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK
OK


Starting kernel ...


Uncompressing Linux.............................................................
................................................................................
.................... done, booting the kernel.
Linux version 2.6.32.2-FriendlyARM (root@debian6) (gcc version 4.4.5 (GCC) ) #2
Fri Sep 23 17:09:08 CST 2011
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=00007177
CPU: VIVT data cache, VIVT instruction cache
Machine: FriendlyARM Mini2440 development board
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, (c) 2004 Simtec Electronics
S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz

    好了就这么多了,还有些东西没有写,是自己操作的问题,希望实践的人自己体会了,希望鄙视的有问题的都留言告诉我。

参考文章:

1.u-boot-2009.08在mini2440上的移植(六)---增加引导内核功能  http://singleboy.blog.163.com/blog/static/54900194201141282946225/

你可能感兴趣的:(linux,image,Debian,gcc,makefile,compression)