]>
Commit | Line | Data |
---|---|---|
6f4e7d3c TG |
1 | Lightweight UBI and UBI fastmap support |
2 | ||
3 | # Copyright (C) Thomas Gleixner <[email protected]> | |
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)); |