From 7e6ee7ad27de5216db1baef76f38c3429c8f4a2a Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:32:36 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 6/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- include/exports.h | 1 + include/jffs2/load_kernel.h | 5 + include/linux/crc32.h | 27 +++++ include/linux/mtd/partitions.h | 84 ++++++++++++++++ include/linux/types.h | 24 +++++ include/ubi_uboot.h | 217 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 358 insertions(+) create mode 100644 include/linux/crc32.h create mode 100644 include/linux/mtd/partitions.h create mode 100644 include/ubi_uboot.h (limited to 'include') diff --git a/include/exports.h b/include/exports.h index 6377875..0620e9e 100644 --- a/include/exports.h +++ b/include/exports.h @@ -25,6 +25,7 @@ char *getenv (char *name); int setenv (char *varname, char *varvalue); long simple_strtol(const char *cp,char **endp,unsigned int base); int strcmp(const char * cs,const char * ct); +int ustrtoul(const char *cp, char **endp, unsigned int base); #ifdef CONFIG_HAS_UID void forceenv (char *varname, char *varvalue); #endif diff --git a/include/jffs2/load_kernel.h b/include/jffs2/load_kernel.h index 551fd0c..e9b7d6e 100644 --- a/include/jffs2/load_kernel.h +++ b/include/jffs2/load_kernel.h @@ -73,4 +73,9 @@ struct mtdids { #define putLabeledWord(x, y) printf("%s %08x\n", x, (unsigned int)y) #define led_blink(x, y, z, a) +/* common/cmd_jffs2.c */ +extern int mtdparts_init(void); +extern int find_dev_and_part(const char *id, struct mtd_device **dev, + u8 *part_num, struct part_info **part); + #endif /* load_kernel_h */ diff --git a/include/linux/crc32.h b/include/linux/crc32.h new file mode 100644 index 0000000..e133157 --- /dev/null +++ b/include/linux/crc32.h @@ -0,0 +1,27 @@ +/* + * crc32.h + * See linux/lib/crc32.c for license and changes + */ +#ifndef _LINUX_CRC32_H +#define _LINUX_CRC32_H + +#include +//#include + +extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); +//extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); + +#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)data, length) + +/* + * Helpers for hash table generation of ethernet nics: + * + * Ethernet sends the least significant bit of a byte first, thus crc32_le + * is used. The output of crc32_le is bit reversed [most significant bit + * is in bit nr 0], thus it must be reversed before use. Except for + * nics that bit swap the result internally... + */ +//#define ether_crc(length, data) bitrev32(crc32_le(~0, data, length)) +//#define ether_crc_le(length, data) crc32_le(~0, data, length) + +#endif /* _LINUX_CRC32_H */ diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h new file mode 100644 index 0000000..b41e5f5 --- /dev/null +++ b/include/linux/mtd/partitions.h @@ -0,0 +1,84 @@ +/* + * MTD partitioning layer definitions + * + * (C) 2000 Nicolas Pitre + * + * This code is GPL + * + * $Id: partitions.h,v 1.17 2005/11/07 11:14:55 gleixner Exp $ + */ + +#ifndef MTD_PARTITIONS_H +#define MTD_PARTITIONS_H + +#include + + +/* + * Partition definition structure: + * + * An array of struct partition is passed along with a MTD object to + * add_mtd_partitions() to create them. + * + * For each partition, these fields are available: + * name: string that will be used to label the partition's MTD device. + * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition + * will extend to the end of the master MTD device. + * offset: absolute starting position within the master MTD device; if + * defined as MTDPART_OFS_APPEND, the partition will start where the + * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. + * mask_flags: contains flags that have to be masked (removed) from the + * master MTD flag set for the corresponding MTD partition. + * For example, to force a read-only partition, simply adding + * MTD_WRITEABLE to the mask_flags will do the trick. + * + * Note: writeable partitions require their size and offset be + * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). + */ + +struct mtd_partition { + char *name; /* identifier string */ + u_int32_t size; /* partition size */ + u_int32_t offset; /* offset within the master MTD space */ + u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ + struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ + struct mtd_info **mtdp; /* pointer to store the MTD object */ +}; + +#define MTDPART_OFS_NXTBLK (-2) +#define MTDPART_OFS_APPEND (-1) +#define MTDPART_SIZ_FULL (0) + + +int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); +int del_mtd_partitions(struct mtd_info *); + +#if 0 +/* + * Functions dealing with the various ways of partitioning the space + */ + +struct mtd_part_parser { + struct list_head list; + struct module *owner; + const char *name; + int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long); +}; + +extern int register_mtd_parser(struct mtd_part_parser *parser); +extern int deregister_mtd_parser(struct mtd_part_parser *parser); +extern int parse_mtd_partitions(struct mtd_info *master, const char **types, + struct mtd_partition **pparts, unsigned long origin); + +#define put_partition_parser(p) do { module_put((p)->owner); } while(0) + +struct device; +struct device_node; + +int __devinit of_mtd_parse_partitions(struct device *dev, + struct mtd_info *mtd, + struct device_node *node, + struct mtd_partition **pparts); +#endif + +#endif diff --git a/include/linux/types.h b/include/linux/types.h index df4808f..1b0b4a4 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -119,6 +119,30 @@ typedef __s64 int64_t; * Below are truly Linux-specific types that should never collide with * any application/library that wants linux/types.h. */ +#ifdef __CHECKER__ +#define __bitwise__ __attribute__((bitwise)) +#else +#define __bitwise__ +#endif +#ifdef __CHECK_ENDIAN__ +#define __bitwise __bitwise__ +#else +#define __bitwise +#endif + +typedef __u16 __bitwise __le16; +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __le32; +typedef __u32 __bitwise __be32; +#if defined(__GNUC__) +typedef __u64 __bitwise __le64; +typedef __u64 __bitwise __be64; +#endif +typedef __u16 __bitwise __sum16; +typedef __u32 __bitwise __wsum; + + +typedef unsigned __bitwise__ gfp_t; struct ustat { __kernel_daddr_t f_tfree; diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h new file mode 100644 index 0000000..295f2c0 --- /dev/null +++ b/include/ubi_uboot.h @@ -0,0 +1,217 @@ +/* + * Header file for UBI support for U-Boot + * + * Adaptation from kernel to U-Boot + * + * Copyright (C) 2005-2007 Samsung Electronics + * Kyungmin Park + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __UBOOT_UBI_H +#define __UBOOT_UBI_H + +#include +#include +#include +#include +#include + +#ifdef CONFIG_CMD_ONENAND +#include +#endif + +#include + +#define DPRINTK(format, args...) \ +do { \ + printf("%s[%d]: " format "\n", __func__, __LINE__, ##args); \ +} while (0) + +/* configurable */ +#define CONFIG_MTD_UBI_WL_THRESHOLD 4096 +#define CONFIG_MTD_UBI_BEB_RESERVE 1 +#define UBI_IO_DEBUG 0 + +/* debug options (Linux: drivers/mtd/ubi/Kconfig.debug) */ +#undef CONFIG_MTD_UBI_DEBUG +#undef CONFIG_MTD_UBI_DEBUG_PARANOID +#undef CONFIG_MTD_UBI_DEBUG_MSG +#undef CONFIG_MTD_UBI_DEBUG_MSG_EBA +#undef CONFIG_MTD_UBI_DEBUG_MSG_WL +#undef CONFIG_MTD_UBI_DEBUG_MSG_IO +#undef CONFIG_MTD_UBI_DEBUG_MSG_BLD +#define CONFIG_MTD_UBI_DEBUG_DISABLE_BGT + +/* compiler options */ +#define uninitialized_var(x) x = x + +/* build.c */ +#define get_device(...) +#define put_device(...) +#define ubi_sysfs_init(...) 0 +#define ubi_sysfs_close(...) do { } while (0) +static inline int is_power_of_2(unsigned long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} + +/* FIXME */ +#define MKDEV(...) 0 +#define MAJOR(dev) 0 +#define MINOR(dev) 0 + +#define alloc_chrdev_region(...) 0 +#define unregister_chrdev_region(...) + +#define class_create(...) __builtin_return_address(0) +#define class_create_file(...) 0 +#define class_remove_file(...) +#define class_destroy(...) +#define misc_register(...) 0 +#define misc_deregister(...) + +/* vmt.c */ +#define device_register(...) 0 +#define volume_sysfs_init(...) 0 +#define volume_sysfs_close(...) do { } while (0) + +/* kapi.c */ + +/* eba.c */ + +/* io.c */ +#define init_waitqueue_head(...) do { } while (0) +#define wait_event_interruptible(...) 0 +#define wake_up_interruptible(...) do { } while (0) +#define print_hex_dump(...) do { } while (0) +#define dump_stack(...) do { } while (0) + +/* wl.c */ +#define task_pid_nr(x) 0 +#define set_freezable(...) do { } while (0) +#define try_to_freeze(...) 0 +#define set_current_state(...) do { } while (0) +#define kthread_should_stop(...) 0 +#define schedule() do { } while (0) + +/* upd.c */ +static inline unsigned long copy_from_user(void *dest, const void *src, + unsigned long count) +{ + memcpy((void *)dest, (void *)src, count); + return 0; +} + +/* common */ +typedef int spinlock_t; +typedef int wait_queue_head_t; +#define spin_lock_init(...) +#define spin_lock(...) +#define spin_unlock(...) + +#define mutex_init(...) +#define mutex_lock(...) +#define mutex_unlock(...) + +#define init_rwsem(...) do { } while (0) +#define down_read(...) do { } while (0) +#define down_write(...) do { } while (0) +#define down_write_trylock(...) 0 +#define up_read(...) do { } while (0) +#define up_write(...) do { } while (0) + +struct kmem_cache { int i; }; +#define kmem_cache_create(...) 1 +#define kmem_cache_alloc(obj, gfp) malloc(sizeof(struct ubi_wl_entry)) +#define kmem_cache_free(obj, size) free(size) +#define kmem_cache_destroy(...) + +#define cond_resched() do { } while (0) +#define yield() do { } while (0) + +#define KERN_WARNING +#define KERN_ERR +#define KERN_NOTICE +#define KERN_DEBUG + +#define GFP_KERNEL 0 +#define GFP_NOFS 1 + +#define __user +#define __init +#define __exit + +#define kthread_create(...) __builtin_return_address(0) +#define kthread_stop(...) do { } while (0) +#define wake_up_process(...) do { } while (0) + +#define BUS_ID_SIZE 20 + +struct rw_semaphore { int i; }; +struct device { + struct device *parent; + struct class *class; + char bus_id[BUS_ID_SIZE]; /* position on parent bus */ + dev_t devt; /* dev_t, creates the sysfs "dev" */ + void (*release)(struct device *dev); +}; +struct mutex { int i; }; +struct kernel_param { int i; }; + +struct cdev { + int owner; + dev_t dev; +}; +#define cdev_init(...) do { } while (0) +#define cdev_add(...) 0 +#define cdev_del(...) do { } while (0) + +#define MAX_ERRNO 4095 +#define IS_ERR_VALUE(x) ((x) >= (unsigned long)-MAX_ERRNO) + +static inline void *ERR_PTR(long error) +{ + return (void *) error; +} + +static inline long PTR_ERR(const void *ptr) +{ + return (long) ptr; +} + +static inline long IS_ERR(const void *ptr) +{ + return IS_ERR_VALUE((unsigned long)ptr); +} + +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) + +/* module */ +#define THIS_MODULE 0 +#define try_module_get(...) 0 +#define module_put(...) do { } while (0) +#define module_init(...) +#define module_exit(...) +#define EXPORT_SYMBOL(...) +#define EXPORT_SYMBOL_GPL(...) +#define module_param_call(...) +#define MODULE_PARM_DESC(...) +#define MODULE_VERSION(...) +#define MODULE_DESCRIPTION(...) +#define MODULE_AUTHOR(...) +#define MODULE_LICENSE(...) + +#include "../drivers/mtd/ubi/ubi.h" + +/* functions */ +extern int ubi_mtd_param_parse(const char *val, struct kernel_param *kp); +extern int ubi_init(void); + +extern struct ubi_device *ubi_devices[]; + +#endif -- cgit v1.1 From 47ae6693f54f80455ae32c2e0d995e0e4bdc15b9 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:36:36 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 7/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- include/linux/mtd/ubi.h | 186 +++++++++++++++++++++++++++++++++ include/mtd/ubi-user.h | 268 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 454 insertions(+) create mode 100644 include/linux/mtd/ubi.h create mode 100644 include/mtd/ubi-user.h (limited to 'include') diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h new file mode 100644 index 0000000..a017891 --- /dev/null +++ b/include/linux/mtd/ubi.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +#ifndef __LINUX_UBI_H__ +#define __LINUX_UBI_H__ + +//#include +#include +#include + +/* + * enum ubi_open_mode - UBI volume open mode constants. + * + * UBI_READONLY: read-only mode + * UBI_READWRITE: read-write mode + * UBI_EXCLUSIVE: exclusive mode + */ +enum { + UBI_READONLY = 1, + UBI_READWRITE, + UBI_EXCLUSIVE +}; + +/** + * struct ubi_volume_info - UBI volume description data structure. + * @vol_id: volume ID + * @ubi_num: UBI device number this volume belongs to + * @size: how many physical eraseblocks are reserved for this volume + * @used_bytes: how many bytes of data this volume contains + * @used_ebs: how many physical eraseblocks of this volume actually contain any + * data + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @corrupted: non-zero if the volume is corrupted (static volumes only) + * @upd_marker: non-zero if the volume has update marker set + * @alignment: volume alignment + * @usable_leb_size: how many bytes are available in logical eraseblocks of + * this volume + * @name_len: volume name length + * @name: volume name + * @cdev: UBI volume character device major and minor numbers + * + * The @corrupted flag is only relevant to static volumes and is always zero + * for dynamic ones. This is because UBI does not care about dynamic volume + * data protection and only cares about protecting static volume data. + * + * The @upd_marker flag is set if the volume update operation was interrupted. + * Before touching the volume data during the update operation, UBI first sets + * the update marker flag for this volume. If the volume update operation was + * further interrupted, the update marker indicates this. If the update marker + * is set, the contents of the volume is certainly damaged and a new volume + * update operation has to be started. + * + * To put it differently, @corrupted and @upd_marker fields have different + * semantics: + * o the @corrupted flag means that this static volume is corrupted for some + * reasons, but not because an interrupted volume update + * o the @upd_marker field means that the volume is damaged because of an + * interrupted update operation. + * + * I.e., the @corrupted flag is never set if the @upd_marker flag is set. + * + * The @used_bytes and @used_ebs fields are only really needed for static + * volumes and contain the number of bytes stored in this static volume and how + * many eraseblock this data occupies. In case of dynamic volumes, the + * @used_bytes field is equivalent to @size*@usable_leb_size, and the @used_ebs + * field is equivalent to @size. + * + * In general, logical eraseblock size is a property of the UBI device, not + * of the UBI volume. Indeed, the logical eraseblock size depends on the + * physical eraseblock size and on how much bytes UBI headers consume. But + * because of the volume alignment (@alignment), the usable size of logical + * eraseblocks if a volume may be less. The following equation is true: + * @usable_leb_size = LEB size - (LEB size mod @alignment), + * where LEB size is the logical eraseblock size defined by the UBI device. + * + * The alignment is multiple to the minimal flash input/output unit size or %1 + * if all the available space is used. + * + * To put this differently, alignment may be considered is a way to change + * volume logical eraseblock sizes. + */ +struct ubi_volume_info { + int ubi_num; + int vol_id; + int size; + long long used_bytes; + int used_ebs; + int vol_type; + int corrupted; + int upd_marker; + int alignment; + int usable_leb_size; + int name_len; + const char *name; + dev_t cdev; +}; + +/** + * struct ubi_device_info - UBI device description data structure. + * @ubi_num: ubi device number + * @leb_size: logical eraseblock size on this UBI device + * @min_io_size: minimal I/O unit size + * @ro_mode: if this device is in read-only mode + * @cdev: UBI character device major and minor numbers + * + * Note, @leb_size is the logical eraseblock size offered by the UBI device. + * Volumes of this UBI device may have smaller logical eraseblock size if their + * alignment is not equivalent to %1. + */ +struct ubi_device_info { + int ubi_num; + int leb_size; + int min_io_size; + int ro_mode; + dev_t cdev; +}; + +/* UBI descriptor given to users when they open UBI volumes */ +struct ubi_volume_desc; + +int ubi_get_device_info(int ubi_num, struct ubi_device_info *di); +void ubi_get_volume_info(struct ubi_volume_desc *desc, + struct ubi_volume_info *vi); +struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode); +struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, + int mode); +void ubi_close_volume(struct ubi_volume_desc *desc); +int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, + int len, int check); +int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, + int offset, int len, int dtype); +int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, + int len, int dtype); +int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum); +int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum); +int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype); +int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum); + +/* + * This function is the same as the 'ubi_leb_read()' function, but it does not + * provide the checking capability. + */ +static inline int ubi_read(struct ubi_volume_desc *desc, int lnum, char *buf, + int offset, int len) +{ + return ubi_leb_read(desc, lnum, buf, offset, len, 0); +} + +/* + * This function is the same as the 'ubi_leb_write()' functions, but it does + * not have the data type argument. + */ +static inline int ubi_write(struct ubi_volume_desc *desc, int lnum, + const void *buf, int offset, int len) +{ + return ubi_leb_write(desc, lnum, buf, offset, len, UBI_UNKNOWN); +} + +/* + * This function is the same as the 'ubi_leb_change()' functions, but it does + * not have the data type argument. + */ +static inline int ubi_change(struct ubi_volume_desc *desc, int lnum, + const void *buf, int len) +{ + return ubi_leb_change(desc, lnum, buf, len, UBI_UNKNOWN); +} + +#endif /* !__LINUX_UBI_H__ */ diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h new file mode 100644 index 0000000..a7421f1 --- /dev/null +++ b/include/mtd/ubi-user.h @@ -0,0 +1,268 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Артём) + */ + +#ifndef __UBI_USER_H__ +#define __UBI_USER_H__ + +/* + * UBI device creation (the same as MTD device attachment) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * MTD devices may be attached using %UBI_IOCATT ioctl command of the UBI + * control device. The caller has to properly fill and pass + * &struct ubi_attach_req object - UBI will attach the MTD device specified in + * the request and return the newly created UBI device number as the ioctl + * return value. + * + * UBI device deletion (the same as MTD device detachment) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * An UBI device maybe deleted with %UBI_IOCDET ioctl command of the UBI + * control device. + * + * UBI volume creation + * ~~~~~~~~~~~~~~~~~~~ + * + * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character + * device. A &struct ubi_mkvol_req object has to be properly filled and a + * pointer to it has to be passed to the IOCTL. + * + * UBI volume deletion + * ~~~~~~~~~~~~~~~~~~~ + * + * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character + * device should be used. A pointer to the 32-bit volume ID hast to be passed + * to the IOCTL. + * + * UBI volume re-size + * ~~~~~~~~~~~~~~~~~~ + * + * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character + * device should be used. A &struct ubi_rsvol_req object has to be properly + * filled and a pointer to it has to be passed to the IOCTL. + * + * UBI volume update + * ~~~~~~~~~~~~~~~~~ + * + * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the + * corresponding UBI volume character device. A pointer to a 64-bit update + * size should be passed to the IOCTL. After this, UBI expects user to write + * this number of bytes to the volume character device. The update is finished + * when the claimed number of bytes is passed. So, the volume update sequence + * is something like: + * + * fd = open("/dev/my_volume"); + * ioctl(fd, UBI_IOCVOLUP, &image_size); + * write(fd, buf, image_size); + * close(fd); + * + * Atomic eraseblock change + * ~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Atomic eraseblock change operation is done via the %UBI_IOCEBCH IOCTL + * command of the corresponding UBI volume character device. A pointer to + * &struct ubi_leb_change_req has to be passed to the IOCTL. Then the user is + * expected to write the requested amount of bytes. This is similar to the + * "volume update" IOCTL. + */ + +/* + * When a new UBI volume or UBI device is created, users may either specify the + * volume/device number they want to create or to let UBI automatically assign + * the number using these constants. + */ +#define UBI_VOL_NUM_AUTO (-1) +#define UBI_DEV_NUM_AUTO (-1) + +/* Maximum volume name length */ +#define UBI_MAX_VOLUME_NAME 127 + +/* IOCTL commands of UBI character devices */ + +#define UBI_IOC_MAGIC 'o' + +/* Create an UBI volume */ +#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req) +/* Remove an UBI volume */ +#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t) +/* Re-size an UBI volume */ +#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req) + +/* IOCTL commands of the UBI control character device */ + +#define UBI_CTRL_IOC_MAGIC 'o' + +/* Attach an MTD device */ +#define UBI_IOCATT _IOW(UBI_CTRL_IOC_MAGIC, 64, struct ubi_attach_req) +/* Detach an MTD device */ +#define UBI_IOCDET _IOW(UBI_CTRL_IOC_MAGIC, 65, int32_t) + +/* IOCTL commands of UBI volume character devices */ + +#define UBI_VOL_IOC_MAGIC 'O' + +/* Start UBI volume update */ +#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) +/* An eraseblock erasure command, used for debugging, disabled by default */ +#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) +/* An atomic eraseblock change command */ +#define UBI_IOCEBCH _IOW(UBI_VOL_IOC_MAGIC, 2, int32_t) + +/* Maximum MTD device name length supported by UBI */ +#define MAX_UBI_MTD_NAME_LEN 127 + +/* + * UBI data type hint constants. + * + * UBI_LONGTERM: long-term data + * UBI_SHORTTERM: short-term data + * UBI_UNKNOWN: data persistence is unknown + * + * These constants are used when data is written to UBI volumes in order to + * help the UBI wear-leveling unit to find more appropriate physical + * eraseblocks. + */ +enum { + UBI_LONGTERM = 1, + UBI_SHORTTERM = 2, + UBI_UNKNOWN = 3, +}; + +/* + * UBI volume type constants. + * + * @UBI_DYNAMIC_VOLUME: dynamic volume + * @UBI_STATIC_VOLUME: static volume + */ +enum { + UBI_DYNAMIC_VOLUME = 3, + UBI_STATIC_VOLUME = 4, +}; + +/** + * struct ubi_attach_req - attach MTD device request. + * @ubi_num: UBI device number to create + * @mtd_num: MTD device number to attach + * @vid_hdr_offset: VID header offset (use defaults if %0) + * @padding: reserved for future, not used, has to be zeroed + * + * This data structure is used to specify MTD device UBI has to attach and the + * parameters it has to use. The number which should be assigned to the new UBI + * device is passed in @ubi_num. UBI may automatically assign the number if + * @UBI_DEV_NUM_AUTO is passed. In this case, the device number is returned in + * @ubi_num. + * + * Most applications should pass %0 in @vid_hdr_offset to make UBI use default + * offset of the VID header within physical eraseblocks. The default offset is + * the next min. I/O unit after the EC header. For example, it will be offset + * 512 in case of a 512 bytes page NAND flash with no sub-page support. Or + * it will be 512 in case of a 2KiB page NAND flash with 4 512-byte sub-pages. + * + * But in rare cases, if this optimizes things, the VID header may be placed to + * a different offset. For example, the boot-loader might do things faster if the + * VID header sits at the end of the first 2KiB NAND page with 4 sub-pages. As + * the boot-loader would not normally need to read EC headers (unless it needs + * UBI in RW mode), it might be faster to calculate ECC. This is weird example, + * but it real-life example. So, in this example, @vid_hdr_offer would be + * 2KiB-64 bytes = 1984. Note, that this position is not even 512-bytes + * aligned, which is OK, as UBI is clever enough to realize this is 4th sub-page + * of the first page and add needed padding. + */ +struct ubi_attach_req { + int32_t ubi_num; + int32_t mtd_num; + int32_t vid_hdr_offset; + uint8_t padding[12]; +}; + +/** + * struct ubi_mkvol_req - volume description data structure used in + * volume creation requests. + * @vol_id: volume number + * @alignment: volume alignment + * @bytes: volume size in bytes + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @padding1: reserved for future, not used, has to be zeroed + * @name_len: volume name length + * @padding2: reserved for future, not used, has to be zeroed + * @name: volume name + * + * This structure is used by user-space programs when creating new volumes. The + * @used_bytes field is only necessary when creating static volumes. + * + * The @alignment field specifies the required alignment of the volume logical + * eraseblock. This means, that the size of logical eraseblocks will be aligned + * to this number, i.e., + * (UBI device logical eraseblock size) mod (@alignment) = 0. + * + * To put it differently, the logical eraseblock of this volume may be slightly + * shortened in order to make it properly aligned. The alignment has to be + * multiple of the flash minimal input/output unit, or %1 to utilize the entire + * available space of logical eraseblocks. + * + * The @alignment field may be useful, for example, when one wants to maintain + * a block device on top of an UBI volume. In this case, it is desirable to fit + * an integer number of blocks in logical eraseblocks of this UBI volume. With + * alignment it is possible to update this volume using plane UBI volume image + * BLOBs, without caring about how to properly align them. + */ +struct ubi_mkvol_req { + int32_t vol_id; + int32_t alignment; + int64_t bytes; + int8_t vol_type; + int8_t padding1; + int16_t name_len; + int8_t padding2[4]; + char name[UBI_MAX_VOLUME_NAME + 1]; +} __attribute__ ((packed)); + +/** + * struct ubi_rsvol_req - a data structure used in volume re-size requests. + * @vol_id: ID of the volume to re-size + * @bytes: new size of the volume in bytes + * + * Re-sizing is possible for both dynamic and static volumes. But while dynamic + * volumes may be re-sized arbitrarily, static volumes cannot be made to be + * smaller then the number of bytes they bear. To arbitrarily shrink a static + * volume, it must be wiped out first (by means of volume update operation with + * zero number of bytes). + */ +struct ubi_rsvol_req { + int64_t bytes; + int32_t vol_id; +} __attribute__ ((packed)); + +/** + * struct ubi_leb_change_req - a data structure used in atomic logical + * eraseblock change requests. + * @lnum: logical eraseblock number to change + * @bytes: how many bytes will be written to the logical eraseblock + * @dtype: data type (%UBI_LONGTERM, %UBI_SHORTTERM, %UBI_UNKNOWN) + * @padding: reserved for future, not used, has to be zeroed + */ +struct ubi_leb_change_req { + int32_t lnum; + int32_t bytes; + uint8_t dtype; + uint8_t padding[7]; +} __attribute__ ((packed)); + +#endif /* __UBI_USER_H__ */ -- cgit v1.1 From 58be3a1056d88c6d05f3e914389282807e69923a Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 19 Nov 2008 16:38:24 +0100 Subject: UBI: Add basic UBI support to U-Boot (Part 8/8) This patch adds basic UBI (Unsorted Block Image) support to U-Boot. It's based on the Linux UBI version and basically has a "OS" translation wrapper that defines most Linux specific calls (spin_lock() etc.) into no-ops. Some source code parts have been uncommented by "#ifdef UBI_LINUX". This makes it easier to compare this version with the Linux version and simplifies future UBI ports/bug-fixes from the Linux version. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- include/linux/mtd/ubi-header.h | 360 ----------------------------------------- include/linux/mtd/ubi-user.h | 161 ------------------ 2 files changed, 521 deletions(-) delete mode 100644 include/linux/mtd/ubi-header.h delete mode 100644 include/linux/mtd/ubi-user.h (limited to 'include') diff --git a/include/linux/mtd/ubi-header.h b/include/linux/mtd/ubi-header.h deleted file mode 100644 index fa479c7..0000000 --- a/include/linux/mtd/ubi-header.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Authors: Artem Bityutskiy (Битюцкий Артём) - * Thomas Gleixner - * Frank Haverkamp - * Oliver Lohmann - * Andreas Arnez - */ - -/* - * This file defines the layout of UBI headers and all the other UBI on-flash - * data structures. May be included by user-space. - */ - -#ifndef __UBI_HEADER_H__ -#define __UBI_HEADER_H__ - -#include - -/* The version of UBI images supported by this implementation */ -#define UBI_VERSION 1 - -/* The highest erase counter value supported by this implementation */ -#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF - -/* The initial CRC32 value used when calculating CRC checksums */ -#define UBI_CRC32_INIT 0xFFFFFFFFU - -/* Erase counter header magic number (ASCII "UBI#") */ -#define UBI_EC_HDR_MAGIC 0x55424923 -/* Volume identifier header magic number (ASCII "UBI!") */ -#define UBI_VID_HDR_MAGIC 0x55424921 - -/* - * Volume type constants used in the volume identifier header. - * - * @UBI_VID_DYNAMIC: dynamic volume - * @UBI_VID_STATIC: static volume - */ -enum { - UBI_VID_DYNAMIC = 1, - UBI_VID_STATIC = 2 -}; - -/* - * Compatibility constants used by internal volumes. - * - * @UBI_COMPAT_DELETE: delete this internal volume before anything is written - * to the flash - * @UBI_COMPAT_RO: attach this device in read-only mode - * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its - * physical eraseblocks, don't allow the wear-leveling unit to move them - * @UBI_COMPAT_REJECT: reject this UBI image - */ -enum { - UBI_COMPAT_DELETE = 1, - UBI_COMPAT_RO = 2, - UBI_COMPAT_PRESERVE = 4, - UBI_COMPAT_REJECT = 5 -}; - -/* - * ubi16_t/ubi32_t/ubi64_t - 16, 32, and 64-bit integers used in UBI on-flash - * data structures. - */ -typedef struct { - uint16_t int16; -} __attribute__ ((packed)) ubi16_t; - -typedef struct { - uint32_t int32; -} __attribute__ ((packed)) ubi32_t; - -typedef struct { - uint64_t int64; -} __attribute__ ((packed)) ubi64_t; - -/* - * In this implementation of UBI uses the big-endian format for on-flash - * integers. The below are the corresponding conversion macros. - */ -#define cpu_to_ubi16(x) ((ubi16_t){__cpu_to_be16(x)}) -#define ubi16_to_cpu(x) ((uint16_t)__be16_to_cpu((x).int16)) - -#define cpu_to_ubi32(x) ((ubi32_t){__cpu_to_be32(x)}) -#define ubi32_to_cpu(x) ((uint32_t)__be32_to_cpu((x).int32)) - -#define cpu_to_ubi64(x) ((ubi64_t){__cpu_to_be64(x)}) -#define ubi64_to_cpu(x) ((uint64_t)__be64_to_cpu((x).int64)) - -/* Sizes of UBI headers */ -#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr) -#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr) - -/* Sizes of UBI headers without the ending CRC */ -#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(ubi32_t)) -#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(ubi32_t)) - -/** - * struct ubi_ec_hdr - UBI erase counter header. - * @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC) - * @version: version of UBI implementation which is supposed to accept this - * UBI image - * @padding1: reserved for future, zeroes - * @ec: the erase counter - * @vid_hdr_offset: where the VID header starts - * @data_offset: where the user data start - * @padding2: reserved for future, zeroes - * @hdr_crc: erase counter header CRC checksum - * - * The erase counter header takes 64 bytes and has a plenty of unused space for - * future usage. The unused fields are zeroed. The @version field is used to - * indicate the version of UBI implementation which is supposed to be able to - * work with this UBI image. If @version is greater then the current UBI - * version, the image is rejected. This may be useful in future if something - * is changed radically. This field is duplicated in the volume identifier - * header. - * - * The @vid_hdr_offset and @data_offset fields contain the offset of the the - * volume identifier header and user data, relative to the beginning of the - * physical eraseblock. These values have to be the same for all physical - * eraseblocks. - */ -struct ubi_ec_hdr { - ubi32_t magic; - uint8_t version; - uint8_t padding1[3]; - ubi64_t ec; /* Warning: the current limit is 31-bit anyway! */ - ubi32_t vid_hdr_offset; - ubi32_t data_offset; - uint8_t padding2[36]; - ubi32_t hdr_crc; -} __attribute__ ((packed)); - -/** - * struct ubi_vid_hdr - on-flash UBI volume identifier header. - * @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC) - * @version: UBI implementation version which is supposed to accept this UBI - * image (%UBI_VERSION) - * @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) - * @copy_flag: if this logical eraseblock was copied from another physical - * eraseblock (for wear-leveling reasons) - * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, - * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) - * @vol_id: ID of this volume - * @lnum: logical eraseblock number - * @leb_ver: version of this logical eraseblock (IMPORTANT: obsolete, to be - * removed, kept only for not breaking older UBI users) - * @data_size: how many bytes of data this logical eraseblock contains - * @used_ebs: total number of used logical eraseblocks in this volume - * @data_pad: how many bytes at the end of this physical eraseblock are not - * used - * @data_crc: CRC checksum of the data stored in this logical eraseblock - * @padding1: reserved for future, zeroes - * @sqnum: sequence number - * @padding2: reserved for future, zeroes - * @hdr_crc: volume identifier header CRC checksum - * - * The @sqnum is the value of the global sequence counter at the time when this - * VID header was created. The global sequence counter is incremented each time - * UBI writes a new VID header to the flash, i.e. when it maps a logical - * eraseblock to a new physical eraseblock. The global sequence counter is an - * unsigned 64-bit integer and we assume it never overflows. The @sqnum - * (sequence number) is used to distinguish between older and newer versions of - * logical eraseblocks. - * - * There are 2 situations when there may be more then one physical eraseblock - * corresponding to the same logical eraseblock, i.e., having the same @vol_id - * and @lnum values in the volume identifier header. Suppose we have a logical - * eraseblock L and it is mapped to the physical eraseblock P. - * - * 1. Because UBI may erase physical eraseblocks asynchronously, the following - * situation is possible: L is asynchronously erased, so P is scheduled for - * erasure, then L is written to,i.e. mapped to another physical eraseblock P1, - * so P1 is written to, then an unclean reboot happens. Result - there are 2 - * physical eraseblocks P and P1 corresponding to the same logical eraseblock - * L. But P1 has greater sequence number, so UBI picks P1 when it attaches the - * flash. - * - * 2. From time to time UBI moves logical eraseblocks to other physical - * eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P - * to P1, and an unclean reboot happens before P is physically erased, there - * are two physical eraseblocks P and P1 corresponding to L and UBI has to - * select one of them when the flash is attached. The @sqnum field says which - * PEB is the original (obviously P will have lower @sqnum) and the copy. But - * it is not enough to select the physical eraseblock with the higher sequence - * number, because the unclean reboot could have happen in the middle of the - * copying process, so the data in P is corrupted. It is also not enough to - * just select the physical eraseblock with lower sequence number, because the - * data there may be old (consider a case if more data was added to P1 after - * the copying). Moreover, the unclean reboot may happen when the erasure of P - * was just started, so it result in unstable P, which is "mostly" OK, but - * still has unstable bits. - * - * UBI uses the @copy_flag field to indicate that this logical eraseblock is a - * copy. UBI also calculates data CRC when the data is moved and stores it at - * the @data_crc field of the copy (P1). So when UBI needs to pick one physical - * eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is - * examined. If it is cleared, the situation* is simple and the newer one is - * picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC - * checksum is correct, this physical eraseblock is selected (P1). Otherwise - * the older one (P) is selected. - * - * Note, there is an obsolete @leb_ver field which was used instead of @sqnum - * in the past. But it is not used anymore and we keep it in order to be able - * to deal with old UBI images. It will be removed at some point. - * - * There are 2 sorts of volumes in UBI: user volumes and internal volumes. - * Internal volumes are not seen from outside and are used for various internal - * UBI purposes. In this implementation there is only one internal volume - the - * layout volume. Internal volumes are the main mechanism of UBI extensions. - * For example, in future one may introduce a journal internal volume. Internal - * volumes have their own reserved range of IDs. - * - * The @compat field is only used for internal volumes and contains the "degree - * of their compatibility". It is always zero for user volumes. This field - * provides a mechanism to introduce UBI extensions and to be still compatible - * with older UBI binaries. For example, if someone introduced a journal in - * future, he would probably use %UBI_COMPAT_DELETE compatibility for the - * journal volume. And in this case, older UBI binaries, which know nothing - * about the journal volume, would just delete this volume and work perfectly - * fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image - * - it just ignores the Ext3fs journal. - * - * The @data_crc field contains the CRC checksum of the contents of the logical - * eraseblock if this is a static volume. In case of dynamic volumes, it does - * not contain the CRC checksum as a rule. The only exception is when the - * data of the physical eraseblock was moved by the wear-leveling unit, then - * the wear-leveling unit calculates the data CRC and stores it in the - * @data_crc field. And of course, the @copy_flag is %in this case. - * - * The @data_size field is used only for static volumes because UBI has to know - * how many bytes of data are stored in this eraseblock. For dynamic volumes, - * this field usually contains zero. The only exception is when the data of the - * physical eraseblock was moved to another physical eraseblock for - * wear-leveling reasons. In this case, UBI calculates CRC checksum of the - * contents and uses both @data_crc and @data_size fields. In this case, the - * @data_size field contains data size. - * - * The @used_ebs field is used only for static volumes and indicates how many - * eraseblocks the data of the volume takes. For dynamic volumes this field is - * not used and always contains zero. - * - * The @data_pad is calculated when volumes are created using the alignment - * parameter. So, effectively, the @data_pad field reduces the size of logical - * eraseblocks of this volume. This is very handy when one uses block-oriented - * software (say, cramfs) on top of the UBI volume. - */ -struct ubi_vid_hdr { - ubi32_t magic; - uint8_t version; - uint8_t vol_type; - uint8_t copy_flag; - uint8_t compat; - ubi32_t vol_id; - ubi32_t lnum; - ubi32_t leb_ver; /* obsolete, to be removed, don't use */ - ubi32_t data_size; - ubi32_t used_ebs; - ubi32_t data_pad; - ubi32_t data_crc; - uint8_t padding1[4]; - ubi64_t sqnum; - uint8_t padding2[12]; - ubi32_t hdr_crc; -} __attribute__ ((packed)); - -/* Internal UBI volumes count */ -#define UBI_INT_VOL_COUNT 1 - -/* - * Starting ID of internal volumes. There is reserved room for 4096 internal - * volumes. - */ -#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) - -/* The layout volume contains the volume table */ - -#define UBI_LAYOUT_VOL_ID UBI_INTERNAL_VOL_START -#define UBI_LAYOUT_VOLUME_EBS 2 -#define UBI_LAYOUT_VOLUME_NAME "layout volume" -#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT - -/* The maximum number of volumes per one UBI device */ -#define UBI_MAX_VOLUMES 128 - -/* The maximum volume name length */ -#define UBI_VOL_NAME_MAX 127 - -/* Size of the volume table record */ -#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record) - -/* Size of the volume table record without the ending CRC */ -#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(ubi32_t)) - -/** - * struct ubi_vtbl_record - a record in the volume table. - * @reserved_pebs: how many physical eraseblocks are reserved for this volume - * @alignment: volume alignment - * @data_pad: how many bytes are unused at the end of the each physical - * eraseblock to satisfy the requested alignment - * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @upd_marker: if volume update was started but not finished - * @name_len: volume name length - * @name: the volume name - * @padding2: reserved, zeroes - * @crc: a CRC32 checksum of the record - * - * The volume table records are stored in the volume table, which is stored in - * the layout volume. The layout volume consists of 2 logical eraseblock, each - * of which contains a copy of the volume table (i.e., the volume table is - * duplicated). The volume table is an array of &struct ubi_vtbl_record - * objects indexed by the volume ID. - * - * If the size of the logical eraseblock is large enough to fit - * %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES - * records. Otherwise, it contains as many records as it can fit (i.e., size of - * logical eraseblock divided by sizeof(struct ubi_vtbl_record)). - * - * The @upd_marker flag is used to implement volume update. It is set to %1 - * before update and set to %0 after the update. So if the update operation was - * interrupted, UBI knows that the volume is corrupted. - * - * The @alignment field is specified when the volume is created and cannot be - * later changed. It may be useful, for example, when a block-oriented file - * system works on top of UBI. The @data_pad field is calculated using the - * logical eraseblock size and @alignment. The alignment must be multiple to the - * minimal flash I/O unit. If @alignment is 1, all the available space of - * the physical eraseblocks is used. - * - * Empty records contain all zeroes and the CRC checksum of those zeroes. - */ -struct ubi_vtbl_record { - ubi32_t reserved_pebs; - ubi32_t alignment; - ubi32_t data_pad; - uint8_t vol_type; - uint8_t upd_marker; - ubi16_t name_len; - uint8_t name[UBI_VOL_NAME_MAX+1]; - uint8_t padding2[24]; - ubi32_t crc; -} __attribute__ ((packed)); - -#endif /* !__UBI_HEADER_H__ */ diff --git a/include/linux/mtd/ubi-user.h b/include/linux/mtd/ubi-user.h deleted file mode 100644 index fe06ded..0000000 --- a/include/linux/mtd/ubi-user.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Artem Bityutskiy (Битюцкий Артём) - */ - -#ifndef __UBI_USER_H__ -#define __UBI_USER_H__ - -/* - * UBI volume creation - * ~~~~~~~~~~~~~~~~~~~ - * - * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character - * device. A &struct ubi_mkvol_req object has to be properly filled and a - * pointer to it has to be passed to the IOCTL. - * - * UBI volume deletion - * ~~~~~~~~~~~~~~~~~~~ - * - * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character - * device should be used. A pointer to the 32-bit volume ID hast to be passed - * to the IOCTL. - * - * UBI volume re-size - * ~~~~~~~~~~~~~~~~~~ - * - * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character - * device should be used. A &struct ubi_rsvol_req object has to be properly - * filled and a pointer to it has to be passed to the IOCTL. - * - * UBI volume update - * ~~~~~~~~~~~~~~~~~ - * - * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the - * corresponding UBI volume character device. A pointer to a 64-bit update - * size should be passed to the IOCTL. After then, UBI expects user to write - * this number of bytes to the volume character device. The update is finished - * when the claimed number of bytes is passed. So, the volume update sequence - * is something like: - * - * fd = open("/dev/my_volume"); - * ioctl(fd, UBI_IOCVOLUP, &image_size); - * write(fd, buf, image_size); - * close(fd); - */ - -/* - * When a new volume is created, users may either specify the volume number they - * want to create or to let UBI automatically assign a volume number using this - * constant. - */ -#define UBI_VOL_NUM_AUTO (-1) - -/* Maximum volume name length */ -#define UBI_MAX_VOLUME_NAME 127 - -/* IOCTL commands of UBI character devices */ - -#define UBI_IOC_MAGIC 'o' - -/* Create an UBI volume */ -#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req) -/* Remove an UBI volume */ -#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t) -/* Re-size an UBI volume */ -#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req) - -/* IOCTL commands of UBI volume character devices */ - -#define UBI_VOL_IOC_MAGIC 'O' - -/* Start UBI volume update */ -#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) -/* An eraseblock erasure command, used for debugging, disabled by default */ -#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) - -/* - * UBI volume type constants. - * - * @UBI_DYNAMIC_VOLUME: dynamic volume - * @UBI_STATIC_VOLUME: static volume - */ -enum { - UBI_DYNAMIC_VOLUME = 3, - UBI_STATIC_VOLUME = 4 -}; - -/** - * struct ubi_mkvol_req - volume description data structure used in - * volume creation requests. - * @vol_id: volume number - * @alignment: volume alignment - * @bytes: volume size in bytes - * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @padding1: reserved for future, not used - * @name_len: volume name length - * @padding2: reserved for future, not used - * @name: volume name - * - * This structure is used by userspace programs when creating new volumes. The - * @used_bytes field is only necessary when creating static volumes. - * - * The @alignment field specifies the required alignment of the volume logical - * eraseblock. This means, that the size of logical eraseblocks will be aligned - * to this number, i.e., - * (UBI device logical eraseblock size) mod (@alignment) = 0. - * - * To put it differently, the logical eraseblock of this volume may be slightly - * shortened in order to make it properly aligned. The alignment has to be - * multiple of the flash minimal input/output unit, or %1 to utilize the entire - * available space of logical eraseblocks. - * - * The @alignment field may be useful, for example, when one wants to maintain - * a block device on top of an UBI volume. In this case, it is desirable to fit - * an integer number of blocks in logical eraseblocks of this UBI volume. With - * alignment it is possible to update this volume using plane UBI volume image - * BLOBs, without caring about how to properly align them. - */ -struct ubi_mkvol_req { - int32_t vol_id; - int32_t alignment; - int64_t bytes; - int8_t vol_type; - int8_t padding1; - int16_t name_len; - int8_t padding2[4]; - char name[UBI_MAX_VOLUME_NAME+1]; -} __attribute__ ((packed)); - -/** - * struct ubi_rsvol_req - a data structure used in volume re-size requests. - * @vol_id: ID of the volume to re-size - * @bytes: new size of the volume in bytes - * - * Re-sizing is possible for both dynamic and static volumes. But while dynamic - * volumes may be re-sized arbitrarily, static volumes cannot be made to be - * smaller then the number of bytes they bear. To arbitrarily shrink a static - * volume, it must be wiped out first (by means of volume update operation with - * zero number of bytes). - */ -struct ubi_rsvol_req { - int64_t bytes; - int32_t vol_id; -} __attribute__ ((packed)); - -#endif /* __UBI_USER_H__ */ -- cgit v1.1 From 8000b086b33a5a81f3f390f37e178db7956dc08b Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Fri, 24 Oct 2008 14:55:33 +0200 Subject: ARM: Add Apollon UBI support To enable UBI on Apollon you need to uncomment the CONFIG_SYS_USE_UBI macro. Signed-off-by: Kyungmin Park Signed-off-by: Stefan Roese --- include/configs/apollon.h | 74 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/configs/apollon.h b/include/configs/apollon.h index d71ed44..dff47fc 100644 --- a/include/configs/apollon.h +++ b/include/configs/apollon.h @@ -53,6 +53,9 @@ #define CONFIG_SYS_USE_NOR 1 #endif +/* uncommnet if you want to use UBI */ +#define CONFIG_SYS_USE_UBI + #include /* get chip and board defs */ #define V_SCLK 12000000 @@ -73,8 +76,9 @@ * Size of malloc() pool */ #define CONFIG_ENV_SIZE SZ_128K /* Total Size of Environment Sector */ -#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_128K) -#define CONFIG_SYS_GBL_DATA_SIZE 128 /* bytes reserved for initial data */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + SZ_1M) +/* bytes reserved for initial data */ +#define CONFIG_SYS_GBL_DATA_SIZE 128 /* * Hardware drivers @@ -116,6 +120,13 @@ #define CONFIG_CMD_DIAG #define CONFIG_CMD_ONENAND +#ifdef CONFIG_SYS_USE_UBI +#define CONFIG_CMD_JFFS2 +#define CONFIG_CMD_UBI +#define CONFIG_RBTREE +#define CONFIG_MTD_PARTITIONS +#endif + #undef CONFIG_CMD_AUTOSCRIPT #ifndef CONFIG_SYS_USE_NOR @@ -133,24 +144,39 @@ #define CONFIG_BOOTFILE "uImage" #define CONFIG_ETHADDR 00:0E:99:00:24:20 -#ifdef CONFIG_APOLLON_PLUS -# define CONFIG_BOOTARGS "root=/dev/nfs rw mem=64M console=ttyS0,115200n8 ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2" +#ifdef CONFIG_APOLLON_PLUS +#define CONFIG_SYS_MEM "mem=64M" +#else +#define CONFIG_SYS_MEM "mem=128" +#endif + +#ifdef CONFIG_SYS_USE_UBI +#define CONFIG_SYS_UBI "ubi.mtd=4" #else -# define CONFIG_BOOTARGS "root=/dev/nfs rw mem=128M console=ttyS0,115200n8 ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2" +#define CONFIG_SYS_UBI "" #endif +#define CONFIG_BOOTARGS "root=/dev/nfs rw " CONFIG_SYS_MEM \ + " console=ttyS0,115200n8" \ + " ip=192.168.116.25:192.168.116.1:192.168.116.1:255.255.255.0:" \ + "apollon:eth0:off nfsroot=/tftpboot/nfsroot profile=2 " \ + CONFIG_SYS_UBI + #define CONFIG_EXTRA_ENV_SETTINGS \ "Image=tftp 0x80008000 Image; go 0x80008000\0" \ "zImage=tftp 0x80180000 zImage; go 0x80180000\0" \ "uImage=tftp 0x80180000 uImage; bootm 0x80180000\0" \ "uboot=tftp 0x80008000 u-boot.bin; go 0x80008000\0" \ - "xloader=tftp 0x80180000 x-load.bin; cp.w 0x80180000 0x00000400 0x1000; go 0x00000400\0" \ + "xloader=tftp 0x80180000 x-load.bin; " \ + " cp.w 0x80180000 0x00000400 0x1000; go 0x00000400\0" \ "syncmode50=mw.w 0x1e442 0xc0c4; mw 0x6800a060 0xe30d1201\0" \ "syncmode=mw.w 0x1e442 0xe0f4; mw 0x6800a060 0xe30d1201\0" \ "norboot=cp32 0x18040000 0x80008000 0x200000; go 0x80008000\0" \ - "oneboot=onenand read 0x80008000 0x40000 0x200000; go 0x80008000\0"\ + "oneboot=onenand read 0x80008000 0x40000 0x200000; go 0x80008000\0" \ "onesyncboot=run syncmode oneboot\0" \ - "updateb=tftp 0x80180000 u-boot-onenand.bin; onenand erase 0x0 0x20000; onenand write 0x80180000 0x0 0x20000\0" \ + "updateb=tftp 0x80180000 u-boot-onenand.bin; " \ + " onenand erase 0x0 0x20000; onenand write 0x80180000 0x0 0x20000\0" \ + "ubi=setenv bootargs ${bootargs} ubi.mtd=4 ${mtdparts}; run uImage\0" \ "bootcmd=run uboot\0" /* @@ -164,14 +190,15 @@ /* Print Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) #define CONFIG_SYS_MAXARGS 16 /* max number of command args */ -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */ - -#define CONFIG_SYS_MEMTEST_START (OMAP2420_SDRC_CS0) /* memtest works on */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +/* memtest works on */ +#define CONFIG_SYS_MEMTEST_START (OMAP2420_SDRC_CS0) #define CONFIG_SYS_MEMTEST_END (OMAP2420_SDRC_CS0+SZ_31M) #undef CONFIG_SYS_CLKS_IN_HZ /* everything, incl board info, in Hz */ - -#define CONFIG_SYS_LOAD_ADDR (OMAP2420_SDRC_CS0) /* default load address */ +/* default load address */ +#define CONFIG_SYS_LOAD_ADDR (OMAP2420_SDRC_CS0) /* The 2420 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) * or by 32KHz clk, or from external sig. This rate is divided by a local @@ -211,13 +238,15 @@ # define CONFIG_SYS_MAX_FLASH_BANKS 1 # define CONFIG_SYS_MAX_FLASH_SECT 1024 /*----------------------------------------------------------------------- - * CFI FLASH driver setup */ -# define CONFIG_SYS_FLASH_CFI 1 /* Flash memory is CFI compliant */ +/* Flash memory is CFI compliant */ +# define CONFIG_SYS_FLASH_CFI 1 # define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ -/* #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 */ /* Use buffered writes (~10x faster) */ -# define CONFIG_SYS_FLASH_PROTECTION 1 /* Use h/w sector protection*/ +/* Use buffered writes (~10x faster) */ +/* #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE 1 */ +/* Use h/w sector protection*/ +# define CONFIG_SYS_FLASH_PROTECTION 1 #else /* !CONFIG_SYS_USE_NOR */ # define CONFIG_SYS_NO_FLASH 1 @@ -228,4 +257,15 @@ #define CONFIG_ENV_IS_IN_ONENAND 1 #define CONFIG_ENV_ADDR 0x00020000 +#ifdef CONFIG_SYS_USE_UBI +#define CONFIG_JFFS2_CMDLINE +#define MTDIDS_DEFAULT "onenand0=onenand" +#define MTDPARTS_DEFAULT "mtdparts=onenand:128k(bootloader)," \ + "128k(params)," \ + "2m(kernel)," \ + "16m(rootfs)," \ + "32m(fs)," \ + "-(ubifs)" +#endif + #endif /* __CONFIG_H */ -- cgit v1.1