Thomas Gleixner | 820d24d | 2016-07-12 20:28:12 +0200 | [diff] [blame] | 1 | Lightweight UBI and UBI fastmap support |
| 2 | |
| 3 | # Copyright (C) Thomas Gleixner <tglx@linutronix.de> |
| 4 | # |
| 5 | # SPDX-License-Identifier: GPL 2.0+ BSD-3-Clause |
| 6 | |
| 7 | Scans the UBI information and loads the requested static volumes into |
| 8 | memory. |
| 9 | |
| 10 | Configuration Options: |
| 11 | |
| 12 | CONFIG_SPL_UBI |
| 13 | Enables the SPL UBI support |
| 14 | |
| 15 | CONFIG_SPL_UBI_MAX_VOL_LEBS |
| 16 | The maximum number of logical eraseblocks which a static volume |
| 17 | to load can contain. Used for sizing the scan data structure |
| 18 | |
| 19 | CONFIG_SPL_UBI_MAX_PEB_SIZE |
| 20 | The maximum physical erase block size. Either a compile time |
| 21 | constant or runtime detection. Used for sizing the scan data |
| 22 | structure |
| 23 | |
| 24 | CONFIG_SPL_UBI_MAX_PEBS |
| 25 | The maximum physical erase block count. Either a compile time |
| 26 | constant or runtime detection. Used for sizing the scan data |
| 27 | structure |
| 28 | |
| 29 | CONFIG_SPL_UBI_VOL_IDS |
| 30 | The maximum volume ids which can be loaded. Used for sizing the |
| 31 | scan data structure. |
| 32 | |
| 33 | Usage notes: |
| 34 | |
| 35 | In the board config file define for example: |
| 36 | |
| 37 | #define CONFIG_SPL_UBI |
| 38 | #define CONFIG_SPL_UBI_MAX_VOL_LEBS 256 |
| 39 | #define CONFIG_SPL_UBI_MAX_PEB_SIZE (256*1024) |
| 40 | #define CONFIG_SPL_UBI_MAX_PEBS 4096 |
| 41 | #define CONFIG_SPL_UBI_VOL_IDS 8 |
| 42 | |
| 43 | The size requirement is roughly as follows: |
| 44 | |
| 45 | 2k for the basic data structure |
| 46 | + CONFIG_SPL_UBI_VOL_IDS * CONFIG_SPL_UBI_MAX_VOL_LEBS * 8 |
| 47 | + CONFIG_SPL_UBI_MAX_PEBS * 64 |
| 48 | + CONFIG_SPL_UBI_MAX_PEB_SIZE * UBI_FM_MAX_BLOCKS |
| 49 | |
| 50 | The last one is big, but I really don't care in that stage. Real world |
| 51 | implementations only use the first couple of blocks, but the code |
| 52 | handles up to UBI_FM_MAX_BLOCKS. |
| 53 | |
| 54 | Given the above configuration example the requirement is about 5M |
| 55 | which is usually not a problem to reserve in the RAM along with the |
| 56 | other areas like the kernel/dts load address. |
| 57 | |
| 58 | So something like this will do the trick: |
| 59 | |
| 60 | #define SPL_FINFO_ADDR 0x80800000 |
| 61 | #define SPL_DTB_LOAD_ADDR 0x81800000 |
| 62 | #define SPL_KERNEL_LOAD_ADDR 0x82000000 |
| 63 | |
| 64 | In the board file, implement the following: |
| 65 | |
| 66 | static struct ubispl_load myvolumes[] = { |
| 67 | { |
| 68 | .vol_id = 0, /* kernel volume */ |
| 69 | .load_addr = (void *)SPL_KERNEL_LOAD_ADDR, |
| 70 | }, |
| 71 | { |
| 72 | .vol_id = 1, /* DT blob */ |
| 73 | .load_addr = (void *)SPL_DTB_LOAD_ADDR, |
| 74 | } |
| 75 | }; |
| 76 | |
| 77 | int spl_start_uboot(void) |
| 78 | { |
| 79 | struct ubispl_info info; |
| 80 | |
| 81 | info.ubi = (struct ubi_scan_info *) SPL_FINFO_ADDR; |
| 82 | info.fastmap = 1; |
| 83 | info.read = nand_spl_read_flash; |
| 84 | |
| 85 | #if COMPILE_TIME_DEFINED |
| 86 | /* |
| 87 | * MY_NAND_NR_SPL_PEBS is the number of physical erase blocks |
| 88 | * in the FLASH which are reserved for the SPL. Think about |
| 89 | * mtd partitions: |
| 90 | * |
| 91 | * part_spl { .start = 0, .end = 4 } |
| 92 | * part_ubi { .start = 4, .end = NR_PEBS } |
| 93 | */ |
| 94 | info.peb_offset = MY_NAND_NR_SPL_PEBS; |
| 95 | info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE; |
| 96 | info.vid_offset = MY_NAND_UBI_VID_OFFS; |
| 97 | info.leb_start = MY_NAND_UBI_DATA_OFFS; |
| 98 | info.peb_count = MY_NAND_UBI_NUM_PEBS; |
| 99 | #else |
| 100 | get_flash_info(&flash_info); |
| 101 | info.peb_offset = MY_NAND_NR_SPL_PEBS; |
| 102 | info.peb_size = flash_info.peb_size; |
| 103 | |
| 104 | /* |
| 105 | * The VID and Data offset depend on the capability of the |
| 106 | * FLASH chip to do subpage writes. |
| 107 | * |
| 108 | * If the flash chip supports subpage writes, then the VID |
| 109 | * header starts at the second subpage. So for 2k pages size |
| 110 | * with 4 subpages the VID offset is 512. The DATA offset is 2k. |
| 111 | * |
| 112 | * If the flash chip does not support subpage writes then the |
| 113 | * VID offset is FLASH_PAGE_SIZE and the DATA offset |
| 114 | * 2 * FLASH_PAGE_SIZE |
| 115 | */ |
| 116 | info.vid_offset = flash_info.vid_offset; |
| 117 | info.leb_start = flash_info.data_offset; |
| 118 | |
| 119 | /* |
| 120 | * The flash reports the total number of erase blocks, so |
| 121 | * we need to subtract the number of blocks which are reserved |
| 122 | * for the SPL itself and not managed by UBI. |
| 123 | */ |
| 124 | info.peb_count = flash_info.peb_count - MY_NAND_NR_SPL_PEBS; |
| 125 | #endif |
| 126 | |
| 127 | ret = ubispl_load_volumes(&info, myvolumes, ARRAY_SIZE(myvolumes); |
| 128 | |
| 129 | .... |
| 130 | |
| 131 | } |
| 132 | |
| 133 | Note: you can load any payload that way. You can even load u-boot from |
| 134 | UBI, so the only non UBI managed FLASH area is the one which is |
| 135 | reserved for the SPL itself and read from the SoC ROM. |
| 136 | |
| 137 | And you can do fallback scenarios: |
| 138 | |
| 139 | if (ubispl_load_volumes(&info, volumes0, ARRAY_SIZE(volumes0))) |
| 140 | if (ubispl_load_volumes(&info, volumes1, ARRAY_SIZE(volumes1))) |
| 141 | ubispl_load_volumes(&info, vol_uboot, ARRAY_SIZE(vol_uboot)); |