不断超越自己,将更强大!
分类: 嵌入式
2016-05-18 23:42:24
经过几天的尝试与摸索,终于把yaffs2根文件系统移植到AT91SAM9261EK上,移植中出现了一些问题,经过查找网络资源并分析,总结,终于测试成功。
(1)Bootstrap V3.8.5 :官方最新release版本,我的开发板为:128M NandFlash,因此需要添加128M NandFlash的型号与参数,在Nand_ids:
at91bootstrap-3.8.5/driver/nandflash.c
static struct nand_chip nand_ids[] = {
/* Samsung K9F2G08U0M 256MB */
{0xecda, 0x800, 0x20000, 0x800, 0x40, 0x0},
/* Samsung K9F1G08U0A 128MB */
{0xecf1, 0x400, 0x20000, 0x800, 0x40, 0x0},
编译方法:
# make mrproper
#make at91sam9261eknf_uboot_defconfig
#make menuconfig
# make CROSS_COMPILE=arm-none-linux-gnueabi-
注意几个地址:Uboot的默认为:0x40000开始,0x80000大小。
(2)Uboot,这里使用较新的,u-boot-2015.10,根据网上的资料,修改加入nand write.yaffs功能,用于基于tftp方式的根文件系统的烧写。如果直接用Atmel官方的,经常烧写失败而无法挂载。
修改的位置如下:
一:在 u-boot-2015.10/common/cmd_nand.c
static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])函数里,添加下面的红色代码:
#ifdef CONFIG_CMD_NAND_TRIMFFS
} else if (!strcmp(s, ".trimffs")) {
if (read) {
printf("Unknown nand command suffix '%s'\n", s);
return 1;
}
ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
maxsize, (u_char *)addr,
WITH_DROP_FFS | WITH_WR_VERIFY);
#endif
#ifdef CONFIG_CMD_NAND_YAFFS
} else if (!strcmp(s, ".yaffs")) {
if (read) {
printf("Unknown nand command suffix '%s'\n", s);
return 1;
}
ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
maxsize, (u_char *)addr,
WITH_YAFFS_OOB);
#endif
static char nand_help_text[] =里,添加下面的红色代码,命令提示用。
"nand read.raw - addr off|partition [count]\n"
"nand write.raw - addr off|partition [count]\n"
" Use read.raw/write.raw to avoid ECC and access the flash as-is.\n"
#ifdef CONFIG_CMD_NAND_YAFFS
"nand write.yaffs - addr off|partition size\n"
" write 'size' bytes starting at offset 'off' with yaffs format\n"
" from memory address 'addr', skipping bad blocks!\n"
" of eraseblocks that contain only 0xFF\n"
#endif
二:在u-boot-2015.10/drivers/mtd/nand/nand_util.c里,添加下面红色的代码。
int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
size_t *actual, loff_t lim, u_char *buffer, int flags)
if (actual)
*actual = 0;
#ifdef CONFIG_CMD_NAND_YAFFS
if (flags & WITH_YAFFS_OOB) {
if (flags & ~WITH_YAFFS_OOB)
return -EINVAL;
int pages;
pages = nand->erasesize / nand->writesize;
blocksize = (pages * nand->oobsize) + nand->erasesize;
if (*length % (nand->writesize + nand->oobsize)) {
printf ("Attempt to write incomplete page"
" in yaffs mode\n");
return -EINVAL;
}
} else
#endif
{
blocksize = nand->erasesize;
}
if (left_to_write < (blocksize - block_offset))
write_size = left_to_write;
else
write_size = blocksize - block_offset;
#ifdef CONFIG_CMD_NAND_YAFFS
if (flags & WITH_YAFFS_OOB) {
int page, pages;
size_t pagesize = nand->writesize;
size_t pagesize_oob = pagesize + nand->oobsize;
struct mtd_oob_ops ops;
ops.len = pagesize;
ops.ooblen = nand->oobsize;
ops.mode = MTD_OPS_RAW; //这里要改为RAW
ops.ooboffs = 0;
pages = write_size / pagesize_oob;
for (page = 0; page < pages; page++) {
WATCHDOG_RESET();
ops.datbuf = p_buffer;
ops.oobbuf = ops.datbuf + pagesize;
rval = nand->_write_oob(nand, offset, &ops);
if (rval != 0)
break;
offset += pagesize;
p_buffer += pagesize_oob;
}
}
else
#endif
{
truncated_write_size = write_size;
#ifdef CONFIG_CMD_NAND_TRIMFFS
if (flags & WITH_DROP_FFS)
truncated_write_size = drop_ffs(nand, p_buffer,
&write_size);
#endif
rval = nand_write(nand, offset, &truncated_write_size,
p_buffer);
if ((flags & WITH_WR_VERIFY) && !rval)
rval = nand_verify(nand, offset,
truncated_write_size, p_buffer);
offset += write_size;
p_buffer += write_size;
} //添加大扩号
三:在include/nand.h中添加如下红色代码:
int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
size_t *actual, loff_t lim, u_char *buffer);
#define WITH_YAFFS_OOB (1 << 0) /* Yaffs2 OOB */
#define WITH_DROP_FFS (1 << 0) /* drop trailing all-0xff pages */
#define WITH_WR_VERIFY (1 << 1) /* verify data was written correctly */
四:在include/configs/at91sam9261ek.h 中添加如下红色代码:
/*
* Command line configuration.
*/
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_NAND
#define CONFIG_CMD_USB
#define CONFIG_CMD_NAND_YAFFS /* Yaffs2 */
以上,就完成了uboot的命令:nand write.yaffs功能。
(3)继续修改Uboot,添加网络相关的参数
/* Ethernet */
#define CONFIG_DRIVER_DM9000
#define CONFIG_DM9000_BASE 0x30000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
#define CONFIG_DM9000_USE_16BIT
#define CONFIG_DM9000_NO_SROM
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_RESET_PHY_R
#define CONFIG_ETHADDR a8:53:3e:26:6a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.9.210
#define CONFIG_SERVERIP 192.168.9.106
/* #define CONFIG_GATEWAYIP 192.168.9.1 */
(4)Uboot添加传递内核的启动参数:
我这里使用NandFlash启动。
/* bootstrap + u-boot + env + linux in nandflash */
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0xc0000
#define CONFIG_ENV_OFFSET_REDUND 0x100000
#define CONFIG_ENV_SIZE 0x20000 /* 1 sector = 128 kB */
#define CONFIG_BOOTCOMMAND "nand read 0x22000000 0x200000 0x300000; bootm"
#define CONFIG_BOOTARGS \
"mem=64M console=ttyS0,115200 earlyprintk " \
"mtdparts=atmel_nand:8M(bootstrap/uboot/kernel)ro,-(rootfs) " \
"root=/dev/mtdblock1 rw rootfstype=yaffs2"
#endif
以上Uboot 基本上修改完了。
(5)编译Uboot的命令:
# make mrproper
#make at91sam9261ek_nandflash_config
#make CROSS_COMPILE=arm-none-linux-gnueabi- all (在tools目录下,可以生成用于制作Linux内核uImage的工具:mkimage)
(6)linux-2.6.32.2 打yaffs2的补丁
# ./patch-ker.sh c m /home/AT91/kernel/linux-2.6.32.2
git clone git://
yaffs2可以为git最新的版本,但是,制作工具需要使用mkyaff2image-128M(修改后的)
(7)Linux 内核的修改:添加yaffs2的文件系统的支持。
(8)修改Linux分区:我这里只有两个区,bootstrap/uboot/kernel 8M+rootfs(剩余的空间)
linux-2.6.32.2/arch/arm/mach-at91/board-sam9261ek.c中,修改如下:
/*
* NAND flash
*/
static struct mtd_partition __initdata ek_nand_partition[] = {
{
.name = "bootstrap/uboot/kernel",
.offset = 0,
.size = SZ_8M,
},
{
.name = "rootfs",
.offset = MTDPART_OFS_NXTBLK,
.size = MTDPART_SIZ_FULL,
},
};
(9)内核的编译:
#make mrproper
#make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueaib- menuconfig
导入arch/arm/configs/at91sam9261ek_defconfig
#make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueaib- uImage(把uboot的工具:mkimage放在/usr/local/sbin/下)
生成uImage,内核编译完成
(10)根文件系统的制作:使用busybox制作好后,设置好启动的脚本。使用yaffs2image-128M打包。
mkyaffs2image-128M rootfs rootfs.img
生所rootfs.img就是根文件系统的镜像。
(11)烧写运行:
Bootstrap 0x0
Uboot 0x40000
Kernel 0x2000000
rootfs.img 使用uboot下的tftp下载到内存,命令如下:
tftp 0x22000000 rootfs.img
nand write.yaffs 0x22000000 0x800000 0xaaabb(这里为tftp下载完成的实际大小,十六进制)
(12)重新上电,运行看看效果,如果挂载成功,则说明yaffs2工作正常,如果不成功,仔细研究一下工具是否正确,文件系统是否正常,可以使用cramfs试一下效果。
(13)运行正常后的打印信息如下:
RomBOOT
AT91Bootstrap 3.8.5 (2016骞?05鏈?17鏃?鏄熸湡浜?21:46:08 CST)
NAND: ONFI not supported
NAND: Manufacturer ID: 0xec Chip ID: 0xf1
WARNING: Fail to disable On-Die ECC
NAND: Press the recovery button (BP4) to recovery
NAND: Using Software ECC
NAND: Image: Copy 0x80000 bytes from 0x40000 to 0x21f00000
NAND: Done to load image
U-Boot 2015.10 (May 18 2016 - 20:29:02 +0800)
CPU: AT91SAM9261
Crystal frequency: 18.432 MHz
CPU clock : 198.656 MHz
Master clock : 99.328 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
NAND: 128 MiB
In: serial
Out: serial
Err: serial
Net: dm9000
dm9000 i/o: 0x30000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 03:31:55:98:a3:44
WARNING: Bad MAC address (uninitialized EEPROM?)
operating at 100M full duplex mode
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x200000, size 0x300000
3145728 bytes read: OK
## Booting kernel from Legacy Image at 22000000 ...
Image Name: Linux-2.6.32.2-AT9261
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1349036 Bytes = 1.3 MiB
Load Address: 20008000
Entry Point: 20008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
Starting kernel ...
Uncompressing Linux..................................................................................... done, booting the kernel.
Linux version 2.6.32.2-AT9261 (root@zhangsz) (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29) ) #1 Tue May 17 23:21:25 CST 2016
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: Atmel AT91SAM9261-EK
Memory policy: ECC disabled, Data cache writeback
Clocks: CPU 198 MHz, master 99 MHz, main 18.432 MHz
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
Kernel command line: mem=64M console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:8M(bootstrap/uboot/kernel)ro,-(rootfs) root=/dev/mtdblock1 rw rootfstype=yaffs2
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 62176KB available (2304K code, 205K data, 104K init, 0K highmem)
Hierarchical RCU implementation.
NR_IRQS:192
AT91: 96 gpio irqs in 3 banks
Console: colour dummy device 80x30
console [ttyS0] enabled
Calibrating delay loop... 99.12 BogoMIPS (lpj=495616)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
bio: create slab
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Switching to clocksource pit
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (double precision)
msgmni has been set to 121
io scheduler noop registered
io scheduler anticipatory registered (default)
atmel_lcdfb atmel_lcdfb.0: backlight control is not available
atmel_lcdfb atmel_lcdfb.0: 150KiB frame buffer at 238c0000 (mapped at ffc00000)
atmel_lcdfb atmel_lcdfb.0: fb0: Atmel LCDC at 0x00600000 (mapped at c4814000), irq 21
atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
brd: module loaded
ssc ssc.1: Atmel SSC device at 0xc4818000 (irq 15)
NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 446 at 0x0000037c0000
Bad eraseblock 994 at 0x000007c40000
2 cmdlinepart partitions found on MTD device atmel_nand
Creating 2 MTD partitions on "atmel_nand":
0x000000000000-0x000000800000 : "bootstrap/uboot/kernel"
0x000000800000-0x000008000000 : "rootfs"
atmel_spi atmel_spi.0: Atmel SPI Controller at 0xfffc8000 (irq 12)
dm9000 Ethernet Driver, V1.31
dm9000 dm9000.0: eth%d: Invalid ethernet MAC address. Please set using ifconfig
eth0: dm9000a at c481e000,c4826044 IRQ 107 MAC: 03:31:55:98:a3:44 (chip)
usbmon: debugfs is not available
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
at91_ohci at91_ohci: AT91 OHCI
at91_ohci at91_ohci: new USB bus registered, assigned bus number 1
at91_ohci at91_ohci: irq 20, io mem 0x00500000
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
udc: at91_udc version 3 May 2006
mice: PS/2 mouse device common for all mice
input: gpio-keys as /devices/platform/gpio-keys/input/input0
ads7846 spi0.2: touchscreen, irq 29
input: ADS7843 Touchscreen as /devices/platform/atmel_spi.0/spi0.2/input/input1
rtc-at91sam9 at91_rtt.0: rtc core: registered at91_rtt as rtc0
IRQ 1/rtc0: IRQF_DISABLED is not guaranteed on shared IRQs
rtc-at91sam9 at91_rtt.0: rtc0: SET TIME!
i2c /dev entries driver
i2c-gpio i2c-gpio: using pins 39 (SDA) and 40 (SCL)
AT91SAM9 Watchdog: sorry, watchdog is disabled
at91_wdt: probe of at91_wdt failed with error -5
TCP cubic registered
NET: Registered protocol family 17
rtc-at91sam9 at91_rtt.0: hctosys: unable to read the hardware clock
yaffs: dev is 32505857 name is "mtdblock1" rw
yaffs: passed flags ""
VFS: Mounted root (yaffs2 filesystem) on device 31:1.
Freeing init memory: 104K
#-----Start /etc/init.d/rcS
------------***AT91SAM9261EK 2016-05-18****------------
dm9000 dm9000.0: WARNING: no IRQ resource flags set.
eth0: link up, 100Mbps, full-duplex, lpa 0x4DE1
AT91 login: root
Password:
login[802]: root login on 'ttyS0'
[root@AT91 /]# ls
bin etc linuxrc proc sys var
boot home lost+found root tmp
dev lib mnt sbin usr
[root@AT91 /]# cd /mnt/
[root@AT91 /mnt]# ls
hello nandflash
[root@AT91 /mnt]#