root/ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/fwupgrade.c

Revision 12376, 4.2 kB (checked in by BrainSlayer, 5 months ago)

merge partition code

Line 
1 /*
2 firmware upgrade code for DD-WRT webflash images
3 */
4
5 #include <redboot.h>
6 #include <cyg/io/flash.h>
7 #include <fis.h>
8 #include <flash_config.h>
9 #include "fwupgrade.h"
10
11 /* some variables from flash.c */
12 extern void *flash_start, *flash_end;
13 extern int flash_block_size, flash_num_blocks;
14 #ifdef CYGOPT_REDBOOT_FIS
15 extern void *fis_work_block;
16 extern void *fis_addr;
17 extern int fisdir_size;         // Size of FIS directory.
18 #endif
19 //extern void _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat);
20 extern void fis_update_directory(void);
21
22 //#define TRACE diag_printf("DBG: %s:%d\n", __FUNCTION__, __LINE__)
23
24 #define TRACE
25
26 #define TRX_MAGIC       0x30524448      /* "HDR0" */
27 #define TRX_VERSION     1
28 #define TRX_MAX_LEN     0x8A0000
29 #define TRX_NO_HEADER   1       /* Do not write TRX header */
30
31 //#if __BYTE_ORDER == __BIG_ENDIAN
32 unsigned int bswap_32(unsigned int *values)
33 {
34         unsigned char *p = (unsigned char *)values;
35         unsigned char a;
36         a = p[3];
37         p[3] = p[0];
38         p[0] = a;
39         a = p[2];
40         p[2] = p[1];
41         p[1] = a;
42         return *values;
43 }
44
45 #define STORE32_LE(X)           bswap_32(X)
46
47 //#elif __BYTE_ORDER == __LITTLE_ENDIAN
48 //#define STORE32_LE(X)         (X)
49 //#else
50 //#error unkown endianness!
51 //#endif
52
53 struct trx_header {
54         unsigned int magic;     /* "HDR0" */
55         unsigned int len;       /* Length of file including header */
56         unsigned int crc32;     /* 32-bit CRC from flag_version to end of file */
57         unsigned int flag_version;      /* 0:15 flags, 16:31 version */
58         unsigned int offsets[3];        /* Offsets of partitions from start of header */
59 };
60
61 extern void fis_init(int argc, char *argv[], int force);
62
63 void addPartition(char *name, unsigned int flashbase, unsigned int memaddr,
64                   unsigned int entryaddr, unsigned int partsize,
65                   unsigned int datasize)
66 {
67         int index;
68         struct fis_image_desc *img = (struct fis_image_desc *)fis_work_block;
69         for (index = 0; index < fisdir_size / sizeof(*img); index++, img++) {
70                 if (img->name[0] == (unsigned char)0xFF) {
71                         break;
72                 }
73         }
74         strcpy(img->name, name);
75         img->flash_base = flashbase;
76         img->mem_base = memaddr;
77         img->entry_point = entryaddr;   // Hope it's been set
78         img->size = partsize;
79         img->data_length = datasize;
80 }
81
82 int fw_check_image_ddwrt(unsigned char *addr, unsigned long maxlen,
83                          int do_flash)
84 {
85         struct trx_header *base = (struct trx_header *)addr;
86         struct trx_header trx;
87         memcpy(&trx, base, sizeof(trx));
88         trx.magic = STORE32_LE(&trx.magic);
89         trx.len = STORE32_LE(&trx.len);
90         trx.crc32 = STORE32_LE(&trx.crc32);
91         if (trx.magic != TRX_MAGIC || trx.len < sizeof(struct trx_header)) {
92                 diag_printf("DD-WRT_FW: Bad trx header\n");
93                 return -1;
94         }
95 //if (STORE32_LE(&trx.flag_version) & TRX_NO_HEADER)
96         trx.len -= sizeof(struct trx_header);
97
98         unsigned int crc;
99         crc =
100             cyg_crc32_accumulate(0xffffffff, (unsigned char *)&trx.flag_version,
101                                  sizeof(struct trx_header) - 12);
102         crc =
103             cyg_crc32_accumulate(crc, addr + sizeof(struct trx_header),
104                                  trx.len);
105         if (crc == trx.crc32) {
106                 if (!do_flash)
107                         diag_printf("DD-WRT_FW: DD-WRT FW CRC Okay\n");
108         } else {
109                 diag_printf
110                     ("DD-WRT_FW: DD-WRT FW CRC Failed (Calculated=0x%08X,Real=0x%08X\n",
111                      crc, trx.crc32);
112                 return -1;
113         }
114         if (do_flash) {
115                 char *arg[] = { "fis", "init" };
116                 fis_init(2, arg, 1);
117                 void *err_addr;
118                 flash_read(fis_addr, fis_work_block, fisdir_size,
119                            (void **)&err_addr);
120                 struct fis_image_desc *img = NULL;
121                 int i, stat;
122                 img = fis_lookup("RedBoot", &i);
123                 if (i != 0) {
124                         diag_printf
125                             ("DD-WRT_FW: RedBoot partition is not the first partition\n");
126                         return -1;
127                 }
128                 unsigned int flash_addr = img->flash_base + img->size;
129                 diag_printf("DD-WRT_FW: flash base is 0x%08X\n", flash_addr);
130                 if ((stat =
131                      flash_erase((void *)flash_addr, trx.len,
132                                  (void **)&err_addr)) != 0) {
133                         diag_printf("DD-WRT_FW: Can't erase region at %p: %s\n",
134                                     err_addr, flash_errmsg(stat));
135                         return -1;
136                 }
137                 if ((stat =
138                      flash_program((void *)flash_addr,
139                                    (void *)(addr + sizeof(struct trx_header)),
140                                    trx.len, (void **)&err_addr)) != 0) {
141                         diag_printf
142                             ("DD-WRT_FW: Can't program region at %p: %s\n",
143                              err_addr, flash_errmsg(stat));
144                         return -1;
145                 }
146                 addPartition("linux", flash_addr, 0x80041000, 0x80041000,
147                              trx.len, trx.len);
148                 fis_update_directory();
149                 diag_printf("DD-WRT_FW: flashing done\n");
150         }
151         return 0;
152 }
Note: See TracBrowser for help on using the browser.