#include <linux/config.h>
#include <linux/mtd/mtd.h>
+const char *mkyaffs_c_version = "$Id: mkyaffs.c,v 1.8 2003-03-12 19:54:07 charles Exp $";
// countBits is a quick way of counting the number of bits in a byte.
// ie. countBits[n] holds the number of 1 bits in a byte with the value n.
*/
unsigned char oobbuf[16];
+unsigned char imgpage[528];
+
+/*
+ * OOB layout
+ */
+
+struct nand_oobinfo yaffs_oobinfo = {
+ useecc: 1,
+ eccpos: {8, 9, 10, 13, 14, 15}
+};
+
+struct nand_oobinfo yaffs_noeccinfo = {
+ useecc: 0,
+};
/*
int main(int argc, char **argv)
{
unsigned long addr;
- int bs, fd, i;
+ unsigned long offset;
+ int fd;
+ int img=-1;
+ int optcnt = 1;
+ int usemtdecc = 0;
+ int imglen = 0;
+ int showHelp = 0;
struct mtd_oob_buf oob = {0, 16, (unsigned char *) &oobbuf};
mtd_info_t meminfo;
erase_info_t erase;
+ struct nand_oobinfo oobsel;
+ if (argc > 1 && strcmp (argv[optcnt], "-?") == 0) {
+ showHelp = 1;
+ }
+
+ if (argc > 1 && strcmp (argv[optcnt], "-h") == 0) {
+ showHelp = 1;
+ }
+
+ if (argc > 1 && strcmp (argv[optcnt], "-e") == 0) {
+ optcnt++;
+ usemtdecc = 1;
+ }
+
+ printf("argc %d sh %d optcnt %d\n",argc, showHelp, optcnt);
+
/* Make sure a device was specified */
- if(argc < 2) {
- printf("usage: %s <mtdname>\n", argv[0]);
+ if(showHelp || argc < (optcnt + 1)) {
+ printf("usage: %s [-e] <mtdname> [image name]\n", argv[0]);
+ printf(" -e Use mtd ecc. Default: do not use mtd ecc\n");
+ printf(" mtdname Name of mtd device\n");
+ printf(" image name Name of optional image file\n\n");
+ printf("Function: Formats a NAND mtd device for YAFFS. If the optional\n"
+ "image file is specified, then the file system is loaded with\n"
+ "this image.\n\n");
exit(1);
}
+ if( argc > (optcnt + 1) &&
+ (img = open(argv[optcnt + 1],O_RDONLY)) == -1) {
+ perror("opening image file");
+ exit(1);
+ }
+
+ if(img >= 0){
+ imglen = lseek(img,0,SEEK_END);
+ if(imglen %528){
+ printf("Image not a multiple of 528 bytes\n");
+ exit(1);
+ }
+ }
+
+ lseek(img,0,SEEK_SET);
+
/* Open the device */
- if((fd = open(argv[1], O_RDWR)) == -1) {
- perror("open flash");
+ if((fd = open(argv[optcnt], O_RDWR)) == -1) {
+ perror("opening flash");
exit(1);
}
exit(1);
}
+ // set the appropriate oob layout selector
+ oobsel = usemtdecc ? yaffs_oobinfo : yaffs_noeccinfo;
+ if (ioctl (fd, MEMSETOOBSEL, &oobsel) != 0) {
+ perror ("MEMSETOOBSEL");
+ close (fd);
+ exit (1);
+ }
+
/* Make sure device page sizes are valid */
if( !(meminfo.oobsize == 16 && meminfo.oobblock == 512))
{
exit(1);
}
+ if(imglen >= 0 &&
+ (imglen/528 +32)*512 > meminfo.size){
+ printf("Image is too big for NAND\n");
+ exit(1);
+ }
+
+ printf("Erasing and programming NAND\n");
for(addr = 0; addr < meminfo.size; addr += meminfo.erasesize)
{
/* Read the OOB data to determine if the block is valid.
exit(1);
}
+ /* Do some programming, but not in the first block */
+
+ if(addr){
+ for(offset = 0; offset <meminfo.erasesize; offset+=512)
+ {
+ if(read(img,imgpage,528) == 528){
+ if (usemtdecc) {
+ imgpage[512+8] = 0xff;
+ imgpage[512+9] = 0xff;
+ imgpage[512+10] = 0xff;
+ imgpage[512+13] = 0xff;
+ imgpage[512+14] = 0xff;
+ imgpage[512+15] = 0xff;
+ }
+ oob.start = addr+offset;
+ oob.length=16;
+ oob.ptr=&imgpage[512];
+ ioctl(fd,MEMWRITEOOB,&oob);
+
+ lseek(fd,addr+offset,SEEK_SET);
+ write(fd,imgpage,512);
+ }
+ }
+ }
+
}
}
+
/* All the tests succeeded */
printf("OK\n");
close(fd);