#define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct ubi_set_vol_prop_req { uint8_t property; uint8_t padding[7]; uint64_t value; } __attribute__((packed)); #define UBI_VOL_IOC_MAGIC 'O' #define UBI_VOL_PROP_DIRECT_WRITE 1 #define UBI_IOCSETVOLPROP _IOW(UBI_VOL_IOC_MAGIC, 6, struct ubi_set_vol_prop_req) void setup(void) { system("modprobe -r ubi 2>/dev/null"); system("modprobe -r nandsim 2>/dev/null || true"); system("modprobe nandsim id_bytes=0xec,0xa1,0x00,0x15 # 128M 128KB 2KB"); system("modprobe ubi mtd=0,2048 fm_autoconvert"); system("ubimkvol -N vol_a -S 990 -n 0 /dev/ubi0"); } int get_leb_info(int *cnt, int *leb_size) { char buf[100]; int fd = open("/sys/class/ubi/ubi0_0/reserved_ebs", O_RDONLY); if (fd < 0) { perror("cannot open reserved_ebs"); return -1; } if (read(fd, buf, 10) < 0) { perror("cannot read reserved_ebs"); return -1; } sscanf(buf, "%d", cnt); close(fd); fd = open("/sys/class/ubi/ubi0_0/usable_eb_size", O_RDONLY); if (fd < 0) { perror("cannot open usable_eb_size"); return -1; } if (read(fd, buf, 10) < 0) { perror("cannot read usable_eb_size"); return -1; } sscanf(buf, "%d", leb_size); close(fd); return 0; } int main(void) { int i, fd, cnt, leb_size; char buf[4096]; struct ubi_set_vol_prop_req r; setup(); if (get_leb_info(&cnt, &leb_size) < 0) return 0; fd = open("/dev/ubi0_0", O_RDWR); if (fd < 0) { perror("cannot open ubi"); return 0; } memset(&r, 0, sizeof(struct ubi_set_vol_prop_req)); r.property = UBI_VOL_PROP_DIRECT_WRITE; r.value = 1; if (ioctl(fd, UBI_IOCSETVOLPROP, &r) < 0) { perror("ioctl fail"); return 0; } for (i = 0; i < cnt; ++i) { if (lseek(fd, i * leb_size, SEEK_SET) != i * leb_size) { perror("seek fail"); return 0; } if (write(fd, buf, 4096) < 0) { perror("write fail"); return 0; } } close(fd); return 0; }