Failing to load Barebox Environment

Gaurav Singh gausinghnsit at gmail.com
Thu Sep 30 02:39:22 EDT 2010


Hi Sascha, Juergen,
I did a rather crude workaround for this. Copied the NAND partition
containing the environment from NAND on startup into a file using
run_command.
run_command("cp /dev/env0 /env_temp",0);
then
envfs_load("/env_temp", "/env")

This is working fine.
I think - overall the enfs_load logic has to be tweaked for NAND devices.

Now I wrote a new enfs_nand_load function - This basically reads a
Page of NAND (which works fine if my env file is less than 4096 :))
into the buffer and manipulates it to prepare the Environment
correctly. So basically we can read the entire environment partition
from NAND in one go and then manipulate it to prepare the env in RAM.

int envfs_nand_load(char *filename, char *dir)
{
        struct envfs_super* super;
        void *buf = NULL, *buf_free = NULL;
        int envfd;
        int fd, ret = 0;
        char *str, *tmp;
        int namelen_full;
        unsigned long size;

        envfd = open(filename, O_RDONLY);
        if (envfd < 0) {
                printf("Open %s %s\n", filename, errno_str());
                return -1;
        }
        /* Reading a Page into Buf */
        size = ENVFS_32(4096);
        buf = xzalloc(size);
        buf_free = buf;
        printf("1\n");
        ret = read(envfd, buf, size);
        if (ret < size) {
                perror("read");
                ret = errno;
                goto out;
        }

        super = (struct envfs_super *)buf;

        if ( ENVFS_32(super->magic) != ENVFS_MAGIC) {
                printf("envfs: wrong magic on %s\n", filename);
                ret = -EIO;
                goto out;
        }

        if (crc32(0, (unsigned char *)super, sizeof(struct envfs_super) - 4)
                   != ENVFS_32(super->sb_crc)) {
                printf("wrong crc on env superblock\n");
                ret = -EIO;
                goto out;
        }

        void *buf2;
        size = ENVFS_32(super->size);
        /* Rest on ENV except Superblock to be kept in buf2 */
        buf2 = (void *)((char *)buf + sizeof(struct envfs_super));

        if (crc32(0, (unsigned char *)buf2, size)
                     != ENVFS_32(super->crc)) {
                printf("wrong crc on env\n");
                ret = -EIO;
                goto out;
        }

        while (size) {
                struct envfs_inode *inode;
                uint32_t inode_size, inode_namelen;

                inode = (struct envfs_inode *)buf2;

                if (ENVFS_32(inode->magic) != ENVFS_INODE_MAGIC) {
                        printf("envfs: wrong magic on %s\n", filename);
                        ret = -EIO;
                        goto out;
                }
                inode_size = ENVFS_32(inode->size);
                inode_namelen = ENVFS_32(inode->namelen);

                debug("loading %s size %d namelen %d\n", inode->data,
                        inode_size, inode_namelen);

                str = concat_path_file(dir, inode->data);
                tmp = strdup(str);
                make_directory(dirname(tmp));
                free(tmp);

                fd = open(str, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                free(str);
                if (fd < 0) {
                        printf("Open %s\n", errno_str());
                        ret = fd;
                        goto out;
                }

                namelen_full = PAD4(inode_namelen);
                ret = write(fd, buf2 + namelen_full + sizeof(struct
envfs_inode),
                                inode_size);
                if (ret < inode_size) {
                        perror("write");
                        ret = errno;
                        close(fd);
                        goto out;
                }

                close(fd);

                buf2 += PAD4(inode_namelen) + PAD4(inode_size) +
                                sizeof(struct envfs_inode);
                size -= PAD4(inode_namelen) + PAD4(inode_size) +
                                sizeof(struct envfs_inode);
        }

        ret = 0;
out:
        close(envfd);
        if (buf_free)
                free(buf_free);
        return ret;
}




On Wed, Sep 29, 2010 at 2:53 PM, Juergen Beisert <jbe at pengutronix.de> wrote:
> Juergen Beisert wrote:
>> Just a note:
>>
>> You configure:
>> > >> devfs_add_partition("nand0", 0x00000, 0x200000, PARTITION_FIXED,
>> > >> "self_raw"); dev_add_bb_dev("self_raw", "self0");
>> > >> devfs_add_partition("nand0", 0x200000, 0x200000, PARTITION_FIXED,
>> > >> "env_raw"); dev_add_bb_dev("env_raw", "env0");
>>
>> And then:
>> > EVB2065> addpart /dev/nand0 4M(barebox)ro,2M(kernel)ro,-(root)
>>
>> Both must match!
>>
>> Try instead:
>>
>> EVB2065> addpart /dev/nand0 256k(barebox)ro,256k(env),2M(kernel)ro,-(root)
>>
>> jbe
>
> Ups, sorry: 0x200000 != 256k (didn't count the '0' right...)
>
> EVB2065> addpart /dev/nand0 2M(barebox)ro,2M(env),2M(kernel)ro,-(root)
>
> jbe
>
> --
> Pengutronix e.K.                              | Juergen Beisert             |
> Linux Solutions for Science and Industry      | Phone: +49-8766-939 228     |
> Vertretung Sued/Muenchen, Germany             | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686              | http://www.pengutronix.de/  |
>



More information about the barebox mailing list