S3C2410_HelloSrc.rar

  • PUDN用户
    了解作者
  • Unix_Linux
    开发工具
  • 14KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 6
    下载次数
  • 2006-07-13 06:32
    上传日期
適用於QT2410(研勤)的ARM,HELLO ARM程式參考
S3C2410_HelloSrc.rar
  • Step3_编译运行程序
  • ecc.c
    3.1KB
  • hello.c
    236B
  • imagewrite
    27.4KB
  • imagewrite.c
    10.5KB
  • www.pudn.com.txt
    218B
内容介绍
/* Nand Flash Image Writing Utility */ /* (C) 2002, Mizi Research Inc. Author: Hwang, Chideok <hwang@mizi.co.kr> */ #define _GNU_SOURCE #include <sys/types.h> #include <unistd.h> #include <ctype.h> #include <sys/ioctl.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <asm/types.h rel='nofollow' onclick='return false;'> #include <linux/mtd/mtd.h> #define MAX_PART 9 #define MAX_RETRY 5 #define PARTITION_OFFSET (~0) #define IS_MTD 1 #define IS_BON 0 typedef struct { ulong offset; ulong size; ulong flag; ulong num_bad_block; unsigned short *bad_blocks; } partition_t; const char part_magic[8] = {'M', 0, 0, 'I', 0, 'Z', 'I', 0}; partition_t parts[MAX_PART]; int num_part; #define NAND_SECTOR_SIZE 512 #define NAND_OOB_SIZE 16 int mtd_fd; mtd_info_t meminfo; int is_bad_block(ulong offset); #include "ecc.c" ulong calc_ecc(char *buf, unsigned char *ecc) { nand_calculate_ecc(buf, ecc); return 0; } int write_oob(char *buf, ulong offset) { int err; struct mtd_oob_buf oob; char oob_buf[NAND_OOB_SIZE]; unsigned char ecc[3]; oob.start = offset; oob.ptr = oob_buf; oob.length = NAND_OOB_SIZE; memset(oob_buf, 0xFF, NAND_OOB_SIZE); calc_ecc(buf, ecc); memcpy(oob_buf + 8, ecc, 3); calc_ecc(buf + 256, ecc); memcpy(oob_buf + 11, ecc, 3); err = ioctl(mtd_fd, MEMWRITEOOB, &oob); if (err) { return 1; } return 0; } int write_block(ulong offset, char *buf) { int i; if (is_bad_block(offset)) return 1; for(i=0; i < (meminfo.erasesize/NAND_SECTOR_SIZE); i++) { if (pwrite(mtd_fd, buf, NAND_SECTOR_SIZE, offset) != NAND_SECTOR_SIZE) return 1; if (write_oob(buf, offset)) return 1; offset += NAND_SECTOR_SIZE; buf += NAND_SECTOR_SIZE; } return 0; } int write_image(ulong offset, int fd, long size) { int bad_block_nr = 0; /* NAND_SECTOR_SIZE*32 > meminfo.erasesize */ char buf[NAND_SECTOR_SIZE*32]; ulong block; unsigned short *bad; int i; printf("size = %ld\n", size); if (offset % meminfo.erasesize) { printf("bad alignment \n"); return -1; } for(i=0;i<num_part;i++) { if (parts[i].offset >= offset) break; } if (i == num_part) i = num_part - 1; if (offset + size > parts[i].offset + parts[i].size) { printf("image is too big for this partition\n"); return -1; } block = (offset - parts[i].offset) / meminfo.erasesize; bad = parts[i].bad_blocks; if (bad) { while(*bad++ <= block) block++; } offset = parts[i].offset + block * meminfo.erasesize; read(fd, buf, meminfo.erasesize); while(size > 0) { if (write_block(offset, buf) == 0) { size -= meminfo.erasesize; if (size > 0) read(fd, buf, meminfo.erasesize); } else { int k; int block_nr = (offset - parts[i].offset)/ meminfo.erasesize; for(k=0;k<parts[i].num_bad_block;k++) { if (block_nr == parts[i].bad_blocks[k]) break; } if (k == parts[i].num_bad_block) { printf("**** warning: new bad block in %d\n", block_nr); exit(1); } bad_block_nr++; } offset += meminfo.erasesize; } printf("bad_block = %d\n", bad_block_nr); return 0; } ulong read_size(char *s) { ulong size = 0; while(isdigit(*s)) { size = size * 10 + *s - '0'; s++; } if (*s == 'M' || *s == 'm') size *= 1024*1024; else if (*s == 'K' || *s == 'k') size *= 1024; else if (*s) { printf("hmm bad size %s\n", s); } return size; } ulong read_flag(char *s) { ulong flag = 0; while ( *s && *s != ':' ) s++; if (*s == 0) return IS_BON; s++; if (*s == 'm' || *s == 'M') flag |= IS_MTD; return flag; } char * parse_filename(char *filename, ulong *offset) { char *delim; delim = strchr(filename, ':'); if (delim == NULL) { *offset = 0; } else { *delim++ = 0; *offset = 0; while(isdigit(*delim)) { *offset = *offset * 10 + *delim - '0'; delim++; } if (*delim == 'M' || *delim == 'm') *offset *= 1024*1024; else if (*delim == 'K' || *delim == 'k') *offset *= 1024; else if (*delim) { printf("hmm bad file offset %s\n", filename); } } return filename; } void mark_bad(ulong offset) { char oobbuf[NAND_OOB_SIZE]; struct mtd_oob_buf oob; oob.start = offset; oob.length = NAND_OOB_SIZE; oob.ptr = oobbuf; memset(oobbuf, 0xff, NAND_OOB_SIZE); oobbuf[5] = 0; ioctl(mtd_fd, MEMWRITEOOB, &oob); } int read_partition(void) { int i, k; struct mtd_oob_buf oob; unsigned char oobbuf[NAND_OOB_SIZE]; char buf[NAND_SECTOR_SIZE]; unsigned int *s; ulong offset = PARTITION_OFFSET; int retry = MAX_RETRY; if (offset > meminfo.size - meminfo.erasesize) offset = meminfo.size - meminfo.erasesize; while(retry-- > 0) { oob.start = offset; oob.length = NAND_OOB_SIZE; oob.ptr = oobbuf; if (ioctl(mtd_fd, MEMREADOOB, &oob) || oobbuf[5] != 0xFF) { offset -= meminfo.erasesize; continue; } if (pread(mtd_fd, buf, NAND_SECTOR_SIZE, offset) != NAND_SECTOR_SIZE) { offset -= meminfo.erasesize; continue; } if (strncmp(buf, part_magic, 8) != 0) { return -1; } break; } if (retry <= 0) return -1; s = (unsigned int *)(buf+8); num_part = *s++; for(i=0;i<num_part;i++) { parts[i].offset = *s++; parts[i].size = *s++; parts[i].flag = *s++; } for(i=0;i<num_part;i++) { parts[i].num_bad_block = *s++; if (parts[i].num_bad_block) { parts[i].bad_blocks = malloc(parts[i].num_bad_block * sizeof(unsigned int)); for(k=0;k<parts[i].num_bad_block;k++) { parts[i].bad_blocks[k] = *s++; } } else { parts[i].bad_blocks = 0; } } return 0; } int write_partition(ulong offset) { unsigned char oobbuf[NAND_OOB_SIZE]; char buf[NAND_SECTOR_SIZE]; erase_info_t erase; unsigned int *s; struct mtd_oob_buf oob; int i, k; oob.start = offset; oob.length = NAND_OOB_SIZE; oob.ptr = oobbuf; if (ioctl(mtd_fd, MEMREADOOB, &oob) || oobbuf[5] != 0xFF) return -1; if (pread(mtd_fd, buf, NAND_SECTOR_SIZE, offset) != NAND_SECTOR_SIZE) { printf("read error: mark bad: offset = %lX\n", offset); mark_bad(offset); return -1; } erase.start = offset; erase.length = meminfo.erasesize; if (ioctl(mtd_fd, MEMERASE, &erase) < 0) { printf("erase error: mark bad: offset = %lX\n", offset); mark_bad(offset); return -1; } memcpy(buf, part_magic, 8); s = (unsigned int *)(buf+8); *s++ = num_part; for(i=0;i<num_part;i++) { *s++ = parts[i].offset; *s++ = parts[i].size; *s++ = parts[i].flag; } for(i=0;i<num_part;i++) { *s++ = parts[i].num_bad_block; for(k=0;k<parts[i].num_bad_block;k++) { *s++ = parts[i].bad_blocks[k]; printf("k = %d block = %d\n", k, parts[i].bad_blocks[k]); } } if (pwrite(mtd_fd, buf, NAND_SECTOR_SIZE, offset) != NAND_SECTOR_SIZE) { printf("write error: offset = %lu\n", offset); mark_bad(offset); return -1; } return 0; } int is_bad_block(ulong offset) { unsigned char oobbuf[NAND_OOB_SIZE]; char buf[NAND_SECTOR_SIZE]; struct mtd_oob_buf oob; erase_info_t erase; erase.start = offset; erase.length = meminfo.erasesize; if (ioctl(mtd_fd, MEMERASE, &erase) < 0) return 1; oob.start = offset; oob.length = NAND_OOB_SIZE; oob.ptr = oobbuf; if (ioctl(mtd_fd, MEMREADOOB, &oob) || oobbuf[5] != 0xFF) return -1; if (pread(mtd_fd, buf, NAND_SECTOR_SIZE, offset) != NAND_SECTOR_SIZE) { printf("read error\n"); mark_bad(offset); return -1; } return 0; } void check_bad_block(void) { int i; unsigned short bad_block[1024]; for(i=0;i<num_part;i++) { ulong offset = parts[i].offset; ulong end = (i + 1 < num_part) ? parts[i+1].offset : meminfo.size; int num_bad = 0; int bad; printf("part = %d end = %ld\n", i, end); while (offset < end) { bad = is_bad_block(offset);
评论
    相关推荐