Chinaunix首页 | 论坛 | 博客
  • 博客访问: 172494
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2016-02-01 12:35
个人简介

不断超越自己,将更强大!

文章分类

全部博文(35)

文章存档

2022年(1)

2017年(5)

2016年(29)

我的朋友

分类: 嵌入式

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 at 0
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]# 

阅读(2242) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~