OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [mtd/] [redboot.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * $Id: redboot.c,v 1.1.1.1 2004-04-15 01:51:41 phoenix Exp $
3
 *
4
 * Parse RedBoot-style Flash Image System (FIS) tables and
5
 * produce a Linux partition array to match.
6
 */
7
 
8
#include <linux/kernel.h>
9
#include <linux/slab.h>
10
 
11
#include <linux/mtd/mtd.h>
12
#include <linux/mtd/partitions.h>
13
 
14
struct fis_image_desc {
15
    unsigned char name[16];      // Null terminated name
16
    unsigned long flash_base;    // Address within FLASH of image
17
    unsigned long mem_base;      // Address in memory where it executes
18
    unsigned long size;          // Length of image
19
    unsigned long entry_point;   // Execution entry point
20
    unsigned long data_length;   // Length of actual data
21
    unsigned char _pad[256-(16+7*sizeof(unsigned long))];
22
    unsigned long desc_cksum;    // Checksum over image descriptor
23
    unsigned long file_cksum;    // Checksum over image data
24
};
25
 
26
struct fis_list {
27
        struct fis_image_desc *img;
28
        struct fis_list *next;
29
};
30
 
31
static inline int redboot_checksum(struct fis_image_desc *img)
32
{
33
        /* RedBoot doesn't actually write the desc_cksum field yet AFAICT */
34
        return 1;
35
}
36
 
37
int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts)
38
{
39
        int nrparts = 0;
40
        struct fis_image_desc *buf;
41
        struct mtd_partition *parts;
42
        struct fis_list *fl = NULL, *tmp_fl;
43
        int ret, i;
44
        size_t retlen;
45
        char *names;
46
        int namelen = 0;
47
 
48
        buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
49
 
50
        if (!buf)
51
                return -ENOMEM;
52
 
53
        /* Read the start of the last erase block */
54
        ret = master->read(master, master->size - master->erasesize,
55
                           PAGE_SIZE, &retlen, (void *)buf);
56
 
57
        if (ret)
58
                goto out;
59
 
60
        if (retlen != PAGE_SIZE) {
61
                ret = -EIO;
62
                goto out;
63
        }
64
 
65
        /* RedBoot image could appear in any of the first three slots */
66
        for (i = 0; i < 3; i++) {
67
                if (!memcmp(buf[i].name, "RedBoot", 8))
68
                        break;
69
        }
70
        if (i == 3) {
71
                /* Didn't find it */
72
                printk(KERN_NOTICE "No RedBoot partition table detected in %s\n",
73
                       master->name);
74
                ret = 0;
75
                goto out;
76
        }
77
 
78
        for (i = 0; i < PAGE_SIZE / sizeof(struct fis_image_desc); i++) {
79
                struct fis_list *new_fl, **prev;
80
 
81
                if (buf[i].name[0] == 0xff)
82
                        break;
83
                if (!redboot_checksum(&buf[i]))
84
                        break;
85
 
86
                new_fl = kmalloc(sizeof(struct fis_list), GFP_KERNEL);
87
                namelen += strlen(buf[i].name)+1;
88
                if (!new_fl) {
89
                        ret = -ENOMEM;
90
                        goto out;
91
                }
92
                new_fl->img = &buf[i];
93
                buf[i].flash_base &= master->size-1;
94
 
95
                /* I'm sure the JFFS2 code has done me permanent damage.
96
                 * I now think the following is _normal_
97
                 */
98
                prev = &fl;
99
                while(*prev && (*prev)->img->flash_base < new_fl->img->flash_base)
100
                        prev = &(*prev)->next;
101
                new_fl->next = *prev;
102
                *prev = new_fl;
103
 
104
                nrparts++;
105
        }
106
        if (fl->img->flash_base)
107
                nrparts++;
108
 
109
        for (tmp_fl = fl; tmp_fl->next; tmp_fl = tmp_fl->next) {
110
                if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base)
111
                        nrparts++;
112
        }
113
        parts = kmalloc(sizeof(*parts)*nrparts + namelen, GFP_KERNEL);
114
 
115
        if (!parts) {
116
                ret = -ENOMEM;
117
                goto out;
118
        }
119
        names = (char *)&parts[nrparts];
120
        memset(parts, 0, sizeof(*parts)*nrparts + namelen);
121
        i=0;
122
 
123
        if (fl->img->flash_base) {
124
               parts[0].name = "unallocated space";
125
               parts[0].size = fl->img->flash_base;
126
               parts[0].offset = 0;
127
        }
128
        for ( ; i<nrparts; i++) {
129
                parts[i].size = fl->img->size;
130
                parts[i].offset = fl->img->flash_base;
131
                parts[i].name = names;
132
 
133
                strcpy(names, fl->img->name);
134
                names += strlen(names)+1;
135
 
136
                if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) {
137
                        i++;
138
                        parts[i].offset = parts[i-1].size + parts[i-1].offset;
139
                        parts[i].size = fl->next->img->flash_base - parts[i].offset;
140
                        parts[i].name = "unallocated space";
141
                }
142
                tmp_fl = fl;
143
                fl = fl->next;
144
                kfree(tmp_fl);
145
        }
146
        ret = nrparts;
147
        *pparts = parts;
148
 out:
149
        while (fl) {
150
                struct fis_list *old = fl;
151
                fl = fl->next;
152
                kfree(old);
153
        }
154
        kfree(buf);
155
        return ret;
156
}
157
 
158
EXPORT_SYMBOL(parse_redboot_partitions);
159
 
160
MODULE_LICENSE("GPL");
161
MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>");
162
MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.