OSDN Git Service

Add MS7619SE
[uclinux-h8/uClinux-dist.git] / user / mtd-utils / doc_loadbios.c
1 #define PROGRAM_NAME "doc_loadbios"
2
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <fcntl.h>
7 #include <time.h>
8 #include <string.h>
9 #include <sys/stat.h>
10 #include <sys/ioctl.h>
11 #include <sys/mount.h>
12
13 #include <mtd/mtd-user.h>
14
15 unsigned char databuf[512];
16
17 int main(int argc,char **argv)
18 {
19         mtd_info_t meminfo;
20         int ifd,ofd;
21         struct stat statbuf;
22         erase_info_t erase;
23         unsigned long retlen, ofs, iplsize, ipltailsize;
24         unsigned char *iplbuf;
25         iplbuf = NULL;
26
27         if (argc < 3) {
28                 fprintf(stderr,"You must specify a device,"
29                                 " the source firmware file and the offset\n");
30                 return 1;
31         }
32
33         // Open and size the device
34         if ((ofd = open(argv[1],O_RDWR)) < 0) {
35                 perror("Open flash device");
36                 return 1;
37         }
38
39         if ((ifd = open(argv[2], O_RDONLY)) < 0) {
40                 perror("Open firmware file\n");
41                 close(ofd);
42                 return 1;
43         }
44
45         if (fstat(ifd, &statbuf) != 0) {
46                 perror("Stat firmware file");
47                 goto error;
48         }
49
50 #if 0
51         if (statbuf.st_size > 65536) {
52                 printf("Firmware too large (%ld bytes)\n",statbuf.st_size);
53                 goto error;
54         }
55 #endif
56
57         if (ioctl(ofd,MEMGETINFO,&meminfo) != 0) {
58                 perror("ioctl(MEMGETINFO)");
59                 goto error;
60         }
61
62         iplsize = (ipltailsize = 0);
63         if (argc >= 4) {
64                 /* DoC Millennium has IPL in the first 1K of flash memory */
65                 /* You may want to specify the offset 1024 to store
66                    the firmware next to IPL. */
67                 iplsize = strtoul(argv[3], NULL, 0);
68                 ipltailsize = iplsize % meminfo.erasesize;
69         }
70
71         if (lseek(ofd, iplsize - ipltailsize, SEEK_SET) < 0) {
72                 perror("lseek");
73                 goto error;
74         }
75
76         if (ipltailsize) {
77                 iplbuf = malloc(ipltailsize);
78                 if (iplbuf == NULL) {
79                         fprintf(stderr, "Not enough memory for IPL tail buffer of"
80                                         " %lu bytes\n", (unsigned long) ipltailsize);
81                         goto error;
82                 }
83                 printf("Reading IPL%s area of length %lu at offset %lu\n",
84                                 (iplsize - ipltailsize) ? " tail" : "",
85                                 (long unsigned) ipltailsize,
86                                 (long unsigned) (iplsize - ipltailsize));
87                 if (read(ofd, iplbuf, ipltailsize) != ipltailsize) {
88                         perror("read");
89                         goto error;
90                 }
91         }
92
93         erase.length = meminfo.erasesize;
94
95         for (ofs = iplsize - ipltailsize ;
96                         ofs < iplsize + statbuf.st_size ;
97                         ofs += meminfo.erasesize) {
98                 erase.start = ofs;
99                 printf("Performing Flash Erase of length %lu at offset %lu\n",
100                                 (long unsigned) erase.length, (long unsigned) erase.start);
101
102                 if (ioctl(ofd,MEMERASE,&erase) != 0) {
103                         perror("ioctl(MEMERASE)");
104                         goto error;
105                 }
106         }
107
108         if (lseek(ofd, iplsize - ipltailsize, SEEK_SET) < 0) {
109                 perror("lseek");
110                 goto error;
111         }
112
113         if (ipltailsize) {
114                 printf("Writing IPL%s area of length %lu at offset %lu\n",
115                                 (iplsize - ipltailsize) ? " tail" : "",
116                                 (long unsigned) ipltailsize,
117                                 (long unsigned) (iplsize - ipltailsize));
118                 if (write(ofd, iplbuf, ipltailsize) != ipltailsize) {
119                         perror("write");
120                         goto error;
121                 }
122         }
123
124         printf("Writing the firmware of length %lu at %lu... ",
125                         (unsigned long) statbuf.st_size,
126                         (unsigned long) iplsize);
127         do {
128                 retlen = read(ifd, databuf, 512);
129                 if (retlen < 512)
130                         memset(databuf+retlen, 0xff, 512-retlen);
131                 if (write(ofd, databuf, 512) != 512) {
132                         perror("write");
133                         goto error;
134                 }
135         } while (retlen == 512);
136         printf("Done.\n");
137
138         if (iplbuf != NULL)
139                 free(iplbuf);
140         close(ifd);
141         close(ofd);
142         return 0;
143
144 error:
145         if (iplbuf != NULL)
146                 free(iplbuf);
147         close(ifd);
148         close(ofd);
149         return 1;
150 }