当前位置:首页 > 单片机 > 单片机
[导读]移植环境1,主机环境:VMare下CentOS 5.5 ,1G内存。2,集成开发环境:Elipse IDE3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-linux-gnueabi-gcc v4.5.1。4,开发板:mini2440,2M nor flash,128M nand flash

移植环境

1,主机环境:VMare下CentOS 5.5 ,1G内存。

2,集成开发环境:Elipse IDE

3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-linux-gnueabi-gcc v4.5.1。

4,开发板:mini2440,2M nor flash,128M nand flash。

5,u-boot版本:u-boot-2009.08

6,linux 版本:linux-2.6.32.2

7,参考文章:

嵌入式linux应用开发完全手册,韦东山,编著。

Mini2440 之Linux 移植开发实战指南

制作linux下根文件系统

系统启动挂载根文件系统时Kernel panic

接上篇,回到nand flash分区的挂载问题

【6】将上篇文章中制作好的mtd-uitls工具位于/root/linux-test/mtdtools/mtd-utils/usrdir/sbin目录下工具复制到已经制作的根文件系统的usr/sbin目录下

[root@localhost mtdtools]# cp -a mtd-utils/usrdir/usr/sbin/* /nfsboot/rootfs/usr/sbin/
[root@localhost mtdtools]#

【7】测试mtd工具的正确性,有关mtd工具的使用请参考mtd-utils 工具的使用

在min2440启动后,在终端中运行

[root@mini2440 /]#flash_info
Illegal instruction
[root@mini2440 /]#

网上搜索发现,illegal instruction是非法指令,出现 illegal instruction 的原因是程序收到了SIGILL信号,而这个信号是cpu在发现非法指令之后发出一个异常,然后由负责处理该异常的内核的ISR对含有这个非法指令的进程发出的。程序收到这个信号,一般就是报告 illegal instruction 错误信息。

可执行程序含有非法指令的原因,一般也就是cpu架构不对,编译时指定的march和实际执行的机器的march不同。这种情况,因为工具链一样,连接脚本一样,所以可执行程序可以执行,不会发生exec format error。但是会包含一些不兼容的指令。还有另外一种可能,就是程序的执行权限不够,比如在目态下运行的程序只能执行非特权指令,一旦CPU遇到特权指令,将产生illegal instruction错误。

在系统运行过程中,处理机状态是动态变化的。从目态转换为管态只能通过中断来实现。从管态到目态的转换可通过修改程序状态字PSW来实现。很有可能是你编译和运行的CPU架构或者内核不一样导致。

另外,linux是sysV风格的UNIX系统,freeBSD是BSD风格的UNIX系统。

编译器支持新的嵌入式应用程序二进制接口标准EABI,而kernel默认并未打开对eabi的支持,编绎使用的是非EABI的编译器。这时需要

Kernel Features --->

[*] Use the ARM EABI to compile the kernel(CONFIG_AEABI=y)
[*] Allow old ABI binaries to run with this kernel (EXPERIMENTA) (CONFIG_OABI_COMPAT=y)


尝试方式一

配置内核打开eabi 和old eabi支持选项,然后复制编译器下lib库文件到目标板lib库中(arm-linux-gcc v4.4.3)

[root@localhost ~]# cp -a /usr/local/arm/4.4.3/lib/ /nfsboot/rootfs/lib
[root@localhost ~]#

然后用arm-linux重新编译生成的工具位于mtdtools/mtd-utils/mtd_install/usr/sbin复制到根目录usr/sbin

[root@localhost ~]# cp -a ./linux-test/mtd-utils-1.4.4/mtd_install/usr/sbin/ /nfsboot/rootfs/usr/sbin

再次启动min2440后,在终端中运行

[root@mini2440 /]#flash_info
Illegal instruction
[root@mini2440 /]#

经过仔细检查,上面的操作有点问题,就是cp的的结果是lib下又建了一个lib目录,sbin下又建了一个sbin目录,现在分别将lib下的lib子目录和sbin下的sbin子目录的文件移动到上一级的目录中,替换掉之前已经存在相应文件,正确的操作

[root@localhost ~]# cp -av /usr/local/arm/4.4.3/lib/* /nfsboot/rootfs/lib

[root@localhost ~]# cp -av ./linux-test/mtd-utils-1.4.4/mtd_install/usr/sbin/* /nfsboot/rootfs/usr/sbin

[root@mini2440 /]#flash_info
Usage: flash_info device

OK,总算得到了可以在目标板上执行的mtd操作工具!

尝试方式二

参考Illegal instruction的解决方法这篇文章,把/usr/local/arm/compiler/arm-none-linux-gnueabi/libc/armv4t/lib目录(也就是你的编译器的库目录)下的所有文件拷贝到根目录的lib目录下,然后修改内核Makefile使CROSS=arm-none-linux-gnueabi- (即v4.5.1版本,arm-linux-是友善官方提供的4.4.3版本)。

(1)修改linux-2.6.32.2根目录下Makefile的CROSS_COMPILE

[root@localhost linux-2.6.32.2]# vim Makefile
打开编辑器后在命令模式下执行

/CROSS

然后定位到

export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?= arm
CROSS_COMPILE ?=arm-none-linux-gnueabi-

# Architecture as present in compile.h
然后保存退出,执行

[root@localhost linux-2.6.32.2]# make clean
[root@localhost linux-2.6.32.2]# make uImage
重新生成uImage映像

(2)将编译内核的编译器用lib库复制到目标板根文件系统的lib目录下

[root@localhost linux-2.6.32.2]# cp -a /usr/local/arm/compiler/arm-none-linux-gnueabi/libc/armv4t/lib/* /nfsboot/rootfs/lib

这里将方式二作为备用处理手段放到这里。

【8】首先了解下/dev/mtd和/dev/mtdblock的区别

(1)/dev/mtdn是linux中的MTD架构中,系统自己实现的mtd分区所对应的字符设备,其里面添加了一些ioctl,支持很多命令,如MEMGETINFO,MEMERASE等。而mtd-util中的flash_eraseall等工具,就是以这些ioctl为基础而实现的工具,实现一些关于flash的操作,比如,mtd工具中的flash_erase等。

if(ioctl(fd,MEMGETINFO,&meminfo) != 0)
{
perror("MEMGETINFO");
close(fd);
exit(1);
}

其中,MEMGETINFO,就是linux mtd中的driversmtdnandmtdchar.c中的:

case MEMGETINFO:
info.type = mtd->type;
info.flags = mtd->flags;
info.size = mtd->size;
info.erasesize = mtd->erasesize;
info.writesize = mtd->writesize;
info.oobsize = mtd->oobsize;
/* The below fields are obsolete */
info.ecctype = -1;
info.eccsize = 0;
if (copy_to_user(argp, &info, sizeof(struct mtd_info_user)))
return -EFAULT;
break;

而/dev/mtdblockn,是NandFlash驱动中,驱动在用add_mtd_partitions()添加MTD设备分区而生成的对应的块设备。根据以上内容也更加明白,为什么不能用nandwrite,flash_eraseall,flash_erase等工具去对/dev/mtdblockn去操作了,因为/dev/mtdblock中不包含对应的ioctl,不支持你这么操作。

(2)mtd char设备的主设备号是90;而mtdblock设备的主设备号是31;

此设备号定义在includelinuxmtdmtd.h中

(3)mtd块设备的大小可以通过查看分区信息来得到:

[root@mini2440 /]#cat proc/partitions
major minor #blocks name

31 0 256 mtdblock0
31 1 128 mtdblock1
31 2 5120 mtdblock2
31 3 125568 mtdblock3
31 4 131072 mtdblock4
[root@mini2440 /]#

上面显示的块设备的大小,是block的数目,每个block是1KB;而每个字符设备,其实就是对应着上面的饿每个设备,即/dev/mtd0对应/dev/mtdblock0,以此类推,换句话说,mtdblockn的一些属性,也就是mtdn的属性,比如大小。

(4)对每个mtd字符设备的操作,比如利用nandwrite去对/dev/mtd0写数据,实际就是操作/dev/mtdblock0。而这些操作里面涉及到得offset都指的是mtd分区内的偏移。比如向/dev/mtd1的offset为0的位置写入数据,实际操作的物理偏移是offset=/dev/mtd0的大小=128KB。

【9】向mtdblock3分区中写入根文件系统

(1)查看分区信息

[root@mini2440 /]#mtd_debug info /dev/mtd3
mtd.type = MTD_NANDFLASH
mtd.flags = MTD_CAP_NANDFLASH
mtd.size = 128581632 (122M)
mtd.erasesize = 131072 (128K)
mtd.writesize = 2048 (2K)
mtd.oobsize = 64
regions = 0

(2)擦除nand的mtd3分区
[root@mini2440 /]#flash_erase dev/mtd3 0x560000 0x1e0
Erasing 128 Kibyte @ 4140000 -- 100 % complete
[root@mini2440 /]#mount -t yaffs dev/mtd3 mnt/yaffs
mount: mounting dev/mtd3 on mnt/yaffs failed: Block device required
[root@mini2440 /]#mount -t yaffs dev/mtdblock3 mnt/yaffs
yaffs: dev is 32505859 name is "mtdblock3" rw

(3)挂载/dev/mtdblock3 到/mnt/yaffs

[root@mini2440 /mnt]#ls yaffs
[root@mini2440 /mnt]#mount -t yaffs /dev/mtdblock3 yaffs
yaffs: dev is 32505859 name is "mtdblock3" rw
yaffs: passed flags ""

(4)将打包好的rootfs.tar.gz文件系统解压到刚刚挂载的yaffs目录下,注意要去掉其结对路径,解压后显示的是根文件系统内容

[root@mini2440 /mnt]#ls yaffs
bin etc lib mnt sbin usr
boot home linuxrc proc sys var
dev init lost+found root tmp www

【10】修改u-boot启动参数,从mtdblock3引导

[u-boot@MINI2440]#setenv bootargs'noinitrd console=ttySAC0,115200 init=/linuxr
c 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'
[u-boot@MINI2440]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x4000000000002 -- 0% complete.
Writing to Nand... done
[u-boot@MINI2440]#

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

双系统将是下述内容的主要介绍对象,通过这篇文章,小编希望大家可以对双系统的相关情况以及信息有所认识和了解,详细内容如下。

关键字: 双系统 Windows Linux

安装Linux操作系统并不复杂,下面是一个大致的步骤指南,以帮助您完成安装。1. 下载Linux发行版:首先,您需要从Linux发行版官方网站下载最新的ISO镜像文件。

关键字: Linux 操作系统 ISO镜像

计算机是由一堆硬件组成的,为了有限的控制这些硬件资源,于是就有了操作系统的产生,操作系统是软件子系统的一部分,是硬件基础上的第一层软件。

关键字: Linux 操作系统 计算机

Linux操作系统是一套免费使用和自由传播的类Unix操作系统,通常被称为GNU/Linux。它是由林纳斯·托瓦兹在1991年首次发布的,并基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。Lin...

关键字: Linux 操作系统

所谓进程间通信就是在不同进程之间传播或交换信息,它是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息;还可以让一个程序能够在同一时间里处理许多用户的需求。

关键字: Linux 进程通信 编程接口

串口通信作为一种最传统的通信方式,在工业自动化、通讯、控制等领域得到广泛使用。

关键字: Linux 串口通信 通讯

2023年11月16日: MikroElektronika(MIKROE) ,作为一家通过提供基于成熟标准的创新式硬软件产品来大幅缩短开发时间的嵌入式解决方案公司,今天宣布推出一款基于单线设备的软硬件开源解决方案Cli...

关键字: 嵌入式 Linux 操作系统

Linux是一种免费使用和自由传播的类Unix操作系统,其内核由林纳斯·本纳第克特·托瓦兹于1991年10月5日首次发布。它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CP...

关键字: Linux 操作系统

本文中,小编将对嵌入式予以介绍,如果你想对它的详细情况有所认识,或者想要增进对它的了解程度,不妨请看以下内容哦。

关键字: 嵌入式 Linux

在这篇文章中,小编将为大家带来嵌入式 Linux的相关报道。如果你对本文即将要讲解的内容存在一定兴趣,不妨继续往下阅读哦。

关键字: 嵌入式 Linux
关闭
关闭