Skip to content

Commit fc9a399

Browse files
jameshilliardsbabic
authored andcommitted
Allow specifying UBI Volumes by MTD path
In cases where the env is in an unattached UBI volume we may need to specify the volume name via the MTD path to attach. For this to work correctly we should first scan for any already attached UBI devices to see if they correspond to the mtd partition number in our configuration, if no corresponding attached mtd devices are found we should attempt to ubiattach to the configured MTD path. Signed-off-by: James Hilliard <[email protected]>
1 parent beb2dc8 commit fc9a399

File tree

2 files changed

+127
-2
lines changed

2 files changed

+127
-2
lines changed

docs/fw_env_config.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ UBI Volume by Name Example
9898
| /dev/ubi0:env | 0x0 | 0x1f000 | 0x1f000 | | |
9999
| /dev/ubi0:redund | 0x0 | 0x1f000 | 0x1f000 | | |
100100

101+
UBI Volume by Name from MTD Path Example
102+
--------------------------
103+
104+
| Device Name | Device Offset | Environment Size | Flash Sector Size | Number of Sectors | Disable Lock Mechanism |
105+
|------------------|---------------|------------------|-------------------|-------------------|------------------------|
106+
| /dev/mtd0:env | 0x0 | 0x1f000 | 0x1f000 | | |
107+
| /dev/mtd0:redund | 0x0 | 0x1f000 | 0x1f000 | | |
108+
101109
Configuration File in YAML
102110
==========================
103111

src/uboot_env.c

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343

4444
#define DEVICE_MTD_NAME "/dev/mtd"
4545
#define DEVICE_UBI_NAME "/dev/ubi"
46+
#define DEVICE_UBI_CTRL "/dev/ubi_ctrl"
47+
#define SYS_UBI "/sys/class/ubi"
48+
#define SYS_UBI_MTD_NUM "/sys/class/ubi/ubi%d/mtd_num"
4649
#define SYS_UBI_VOLUME_COUNT "/sys/class/ubi/ubi%d/volumes_count"
4750
#define SYS_UBI_VOLUME_NAME "/sys/class/ubi/ubi%d/ubi%d_%d/name"
4851

@@ -196,7 +199,11 @@ static enum device_type get_device_type(char *device)
196199
enum device_type type = DEVICE_NONE;
197200

198201
if (!strncmp(device, DEVICE_MTD_NAME, strlen(DEVICE_MTD_NAME)))
199-
type = DEVICE_MTD;
202+
if (strchr(device, DEVNAME_SEPARATOR)) {
203+
type = DEVICE_UBI;
204+
} else {
205+
type = DEVICE_MTD;
206+
}
200207
else if (!strncmp(device, DEVICE_UBI_NAME, strlen(DEVICE_UBI_NAME)))
201208
type = DEVICE_UBI;
202209
else if (strlen(device) > 0)
@@ -217,6 +224,77 @@ static int ubi_get_dev_id(char *device)
217224
return dev_id;
218225
}
219226

227+
static int mtd_get_dev_id(char *device)
228+
{
229+
int dev_id = -1;
230+
char *sep;
231+
232+
sep = strrchr(device, 'd');
233+
if (sep)
234+
sscanf(sep + 1, "%d", &dev_id);
235+
236+
return dev_id;
237+
}
238+
239+
static int ubi_get_dev_id_from_mtd(char *device)
240+
{
241+
DIR *sysfs_ubi;
242+
struct dirent *dirent;
243+
int mtd_id;
244+
245+
mtd_id = mtd_get_dev_id(device);
246+
if (mtd_id < 0)
247+
return -1;
248+
249+
sysfs_ubi = opendir(SYS_UBI);
250+
if (!sysfs_ubi)
251+
return -1;
252+
253+
while (1) {
254+
int ubi_num, ret;
255+
256+
dirent = readdir(sysfs_ubi);
257+
if (!dirent)
258+
break;
259+
260+
if (strlen(dirent->d_name) >= 255) {
261+
closedir(sysfs_ubi);
262+
return -1;
263+
}
264+
265+
ret = sscanf(dirent->d_name, "ubi%d", &ubi_num);
266+
if (ret == 1) {
267+
char filename[DEVNAME_MAX_LENGTH];
268+
char data[DEVNAME_MAX_LENGTH];
269+
int fd, n, num_mtd = -1;
270+
271+
snprintf(filename, sizeof(filename), SYS_UBI_MTD_NUM, ubi_num);
272+
fd = open(filename, O_RDONLY);
273+
if (fd < 0)
274+
continue;
275+
276+
n = read(fd, data, sizeof(data));
277+
close(fd);
278+
if (n < 0)
279+
continue;
280+
281+
if (sscanf(data, "%d", &num_mtd) != 1)
282+
num_mtd = -1;
283+
284+
if (num_mtd < 0)
285+
continue;
286+
287+
if (num_mtd == mtd_id) {
288+
closedir(sysfs_ubi);
289+
return ubi_num;
290+
}
291+
}
292+
}
293+
294+
closedir(sysfs_ubi);
295+
return -1;
296+
}
297+
220298
static int ubi_get_num_volume(char *device)
221299
{
222300
char filename[DEVNAME_MAX_LENGTH];
@@ -308,9 +386,48 @@ static int ubi_update_name(struct uboot_flash_env *dev)
308386
{
309387
char device[DEVNAME_MAX_LENGTH];
310388
char volume[DEVNAME_MAX_LENGTH];
311-
int dev_id, vol_id, ret = -EBADF;
389+
int dev_id, vol_id, fd, ret = -EBADF;
390+
struct stat st;
312391
char *sep;
313392

393+
if (!strncmp(dev->devname, DEVICE_MTD_NAME, strlen(DEVICE_MTD_NAME)))
394+
{
395+
sep = strchr(dev->devname, DEVNAME_SEPARATOR);
396+
if (sep)
397+
{
398+
memset(device, 0, DEVNAME_MAX_LENGTH);
399+
memcpy(device, dev->devname, sep - dev->devname);
400+
401+
memset(volume, 0, DEVNAME_MAX_LENGTH);
402+
sscanf(sep + 1, "%s", &volume[0]);
403+
404+
ret = ubi_get_dev_id_from_mtd(device);
405+
if (ret < 0) {
406+
struct ubi_attach_req req;
407+
408+
memset(&req, 0, sizeof(struct ubi_attach_req));
409+
req.ubi_num = UBI_DEV_NUM_AUTO;
410+
req.mtd_num = mtd_get_dev_id(device);
411+
req.vid_hdr_offset = 0;
412+
413+
fd = open(DEVICE_UBI_CTRL, O_RDONLY);
414+
if (fd == -1)
415+
return -EBADF;
416+
417+
ret = ioctl(fd, UBI_IOCATT, &req);
418+
close(fd);
419+
if (ret == -1)
420+
return -EBADF;
421+
422+
sprintf(dev->devname, DEVICE_UBI_NAME"%d:%s", req.ubi_num, volume);
423+
} else {
424+
sprintf(dev->devname, DEVICE_UBI_NAME"%d:%s", ret, volume);
425+
}
426+
} else {
427+
return -EBADF;
428+
}
429+
}
430+
314431
sep = strchr(dev->devname, DEVNAME_SEPARATOR);
315432
if (sep)
316433
{

0 commit comments

Comments
 (0)