| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- /*
- * Copyright (C) 2015 - 2018, IBEROXARXA SERVICIOS INTEGRALES, S.L.
- * Copyright (C) 2015 - 2018, Jaume Olivé Petrus (jolive@whitecatboard.org)
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the <organization> nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * * The WHITECAT logotype cannot be changed, you can remove it, but you
- * cannot change it in any way. The WHITECAT logotype is:
- *
- * /\ /\
- * / \_____/ \
- * /_____________\
- * W H I T E C A T
- *
- * * Redistributions in binary form must retain all copyright notices printed
- * to any local or remote output device. This include any reference to
- * Lua RTOS, whitecatboard.org, Lua, and other copyright notices that may
- * appear in the future.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Lua RTOS, a tool for make a LFS file system image
- *
- */
- #include "lfs/lfs.h"
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <limits.h>
- #include <dirent.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- static struct lfs_config cfg;
- static lfs_t lfs;
- static uint8_t *data;
- static int lfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
- memcpy(buffer, data + (block * c->block_size) + off, size);
- return 0;
- }
- static int lfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
- memcpy(data + (block * c->block_size) + off, buffer, size);
- return 0;
- }
- static int lfs_erase(const struct lfs_config *c, lfs_block_t block) {
- memset(data + (block * c->block_size), 0, c->block_size);
- return 0;
- }
- static int lfs_sync(const struct lfs_config *c) {
- return 0;
- }
- static void create_dir(char *src) {
- char *path;
- int ret;
- path = strchr(src, '/');
- if (path) {
- fprintf(stdout, "%s\r\n", path);
- if ((ret = lfs_mkdir(&lfs, path)) < 0) {
- fprintf(stderr,"can't create directory %s: error=%d\r\n", path, ret);
- exit(1);
- }
- }
- }
- static void create_file(char *src) {
- char *path;
- int ret;
- path = strchr(src, '/');
- if (path) {
- fprintf(stdout, "%s\r\n", path);
- // Open source file
- FILE *srcf = fopen(src,"rb");
- if (!srcf) {
- fprintf(stderr,"can't open source file %s: errno=%d (%s)\r\n", src, errno, strerror(errno));
- exit(1);
- }
- // Open destination file
- lfs_file_t dstf;
- if ((ret = lfs_file_open(&lfs, &dstf, path, LFS_O_WRONLY | LFS_O_CREAT)) < 0) {
- fprintf(stderr,"can't open destination file %s: error=%d\r\n", path, ret);
- exit(1);
- }
- char c = fgetc(srcf);
- while (!feof(srcf)) {
- ret = lfs_file_write(&lfs, &dstf, &c, 1);
- if (ret < 0) {
- fprintf(stderr,"can't write to destination file %s: error=%d\r\n", path, ret);
- exit(1);
- }
- c = fgetc(srcf);
- }
- // Close destination file
- ret = lfs_file_close(&lfs, &dstf);
- if (ret < 0) {
- fprintf(stderr,"can't close destination file %s: error=%d\r\n", path, ret);
- exit(1);
- }
- // Close source file
- fclose(srcf);
- }
- }
- static void compact(char *src) {
- DIR *dir;
- struct dirent *ent;
- char curr_path[PATH_MAX];
- struct stat _stat;
- unsigned int cnt = 0;
- dir = opendir(src);
- if (dir) {
- while ((ent = readdir(dir))) {
- // Skip . and .. directories
- if ((strcmp(ent->d_name,".") != 0) && (strcmp(ent->d_name,"..") != 0)) {
- cnt++;
- // Update the current path
- strcpy(curr_path, src);
- strcat(curr_path, "/");
- strcat(curr_path, ent->d_name);
-
- stat(curr_path, &_stat);
- if (S_ISDIR(_stat.st_mode)) {
- create_dir(curr_path);
- compact(curr_path);
- } else if (S_ISREG(_stat.st_mode)) {
- create_file(curr_path);
- }
- }
- }
- closedir(dir);
- if(cnt == 0) exit(1);
- }else{
- exit(1);
- }
- }
- void usage() {
- fprintf(stdout, "usage: mklfs -c <pack-dir> -b <block-size> -r <read-size> -p <prog-size> -s <filesystem-size> -i <image-file-path>\r\n");
- }
- static int is_number(const char *s) {
- const char *c = s;
- while (*c) {
- if ((*c < '0') || (*c > '9')) {
- return 0;
- }
- c++;
- }
- return 1;
- }
- static int is_hex(const char *s) {
- const char *c = s;
- if (*c++ != '0') {
- return 0;
- }
- if (*c++ != 'x') {
- return 0;
- }
- while (*c) {
- if (((*c < '0') || (*c > '9')) && ((*c < 'A') || (*c > 'F')) && ((*c < 'a') || (*c > 'f'))) {
- return 0;
- }
- c++;
- }
- return 1;
- }
- static int to_int(const char *s) {
- if (is_number(s)) {
- return atoi(s);
- } else if (is_hex(s)) {
- return (int)strtol(s, NULL, 16);
- }
- return -1;
- }
- #define FLASH_FS_REGION_OFFSET 0x350000
- #define FLASH_FS_REGION_END 0x3A4000
- #define FLASH_FS_REGION_SIZE (FLASH_FS_REGION_END-FLASH_FS_REGION_OFFSET) // 336KB
- #define LFS_BLOCK_DEVICE_READ_SIZE (256)
- #define LFS_BLOCK_DEVICE_PROG_SIZE (256)
- #define LFS_BLOCK_DEVICE_ERASE_SIZE (4096) // one sector 4KB
- #define LFS_BLOCK_DEVICE_TOTOAL_SIZE (FLASH_FS_REGION_SIZE)
- #define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
- #define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
- int main(int argc, char **argv) {
- char *src = "disk"; // Source directory
- char *dst = "disk.fs"; // Destination image
- int err = 0;
- int fs_size = LFS_BLOCK_DEVICE_TOTOAL_SIZE;
- if (argc > 1 && !strcmp("-size", argv[1])) {
- fs_size = atoi(argv[2]) * 1024;
- }
- for (size_t i = 0; i < argc; i++)
- {
- //printf("argv[%d] %s\n", i, argv[i]);
- }
-
- // Mount the file system
- cfg.read = lfs_read;
- cfg.prog = lfs_prog;
- cfg.erase = lfs_erase;
- cfg.sync = lfs_sync;
- cfg.read_size = LFS_BLOCK_DEVICE_READ_SIZE;
- cfg.prog_size = LFS_BLOCK_DEVICE_PROG_SIZE;
- cfg.block_size = LFS_BLOCK_DEVICE_ERASE_SIZE;
- cfg.block_count = fs_size / LFS_BLOCK_DEVICE_ERASE_SIZE;
- cfg.block_cycles = 200;
- cfg.cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE;
- cfg.lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
- // cfg.read_buffer = lfs_read_buf,
- // cfg.prog_buffer = lfs_prog_buf,
- // cfg.lookahead_buffer = lfs_lookahead_buf,
- cfg.name_max = 63;
- cfg.file_max = 0;
- cfg.attr_max = 0;
- data = calloc(1, fs_size);
- if (!data) {
- fprintf(stderr, "no memory for mount\r\n");
- return -1;
- }
- err = lfs_format(&lfs, &cfg);
- if (err < 0) {
- fprintf(stderr, "format error: error=%d\r\n", err);
- return -1;
- }
- err = lfs_mount(&lfs, &cfg);
- if (err < 0) {
- fprintf(stderr, "mount error: error=%d\r\n", err);
- return -1;
- }
- compact(src);
- FILE *img = fopen(dst, "wb");
- if (!img) {
- fprintf(stderr, "can't create image file: errno=%d (%s)\r\n", errno, strerror(errno));
- return -1;
- }
- fwrite(data, 1, fs_size, img);
- fclose(img);
- return 0;
- }
|