]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_fat.c
Patch by Kenneth Johansson, 30 Jun 2003:
[karo-tx-uboot.git] / common / cmd_fat.c
1 /*
2  * (C) Copyright 2002
3  * Richard Jones, rjones@nexus-tech.net
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /*
25  * Boot support
26  */
27 #include <common.h>
28 #include <command.h>
29 #include <s_record.h>
30 #include <net.h>
31 #include <ata.h>
32
33 #if (CONFIG_COMMANDS & CFG_CMD_FAT)
34
35 #undef  DEBUG
36
37 #include <fat.h>
38
39 extern block_dev_desc_t *ide_get_dev (int dev);
40
41 int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
42 {
43         long size;
44         unsigned long offset;
45         unsigned long count;
46
47         if (argc < 3) {
48                 printf ("usage:fatload <filename> <addr> [bytes]\n");
49                 return (0);
50         }
51
52         offset = simple_strtoul (argv[2], NULL, 16);
53         if (argc == 4)
54                 count = simple_strtoul (argv[3], NULL, 16);
55         else
56                 count = 0;
57
58         size = file_fat_read (argv[1], (unsigned char *) offset, count);
59
60         printf ("%ld bytes read\n", size);
61
62         return size;
63 }
64
65 U_BOOT_CMD(
66         fatload,        4,      0,      do_fat_fsload,
67         "fatload - load binary file from a dos filesystem\n",
68         "[ off ] [ filename ]\n"
69         "    - load binary file from dos filesystem\n"
70         "      with offset 'off'\n"
71 );
72
73 int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
74 {
75         char *filename = "/";
76         int ret;
77
78         if (argc == 2)
79                 ret = file_fat_ls (argv[1]);
80         else
81                 ret = file_fat_ls (filename);
82
83         return (ret);
84 }
85
86 U_BOOT_CMD(
87         fatls,  2,      1,      do_fat_ls,
88         "fatls   - list files in a directory (default /)\n",
89         "[ directory ]\n"
90         "    - list files in a directory\n"
91 );
92
93 int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
94 {
95         int ret;
96
97         ret = 0;
98
99         printf ("FAT info: %d\n", file_fat_detectfs ());
100
101         return (ret);
102 }
103
104 U_BOOT_CMD(
105         fatinfo,        1,      1,      do_fat_fsinfo,
106         "fatinfo - print information about filesystem\n",
107         "\n"
108         "    - print information about filesystem\n"
109 );
110
111 #ifdef NOT_IMPLEMENTED_YET
112 /* find first device whose first partition is a DOS filesystem */
113 int find_fat_partition (void)
114 {
115         int i, j;
116         block_dev_desc_t *dev_desc;
117         unsigned char *part_table;
118         unsigned char buffer[ATA_BLOCKSIZE];
119
120         for (i = 0; i < CFG_IDE_MAXDEVICE; i++) {
121                 dev_desc = ide_get_dev (i);
122                 if (!dev_desc) {
123                         debug ("couldn't get ide device!\n");
124                         return (-1);
125                 }
126                 if (dev_desc->part_type == PART_TYPE_DOS) {
127                         if (dev_desc->
128                                 block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
129                                 debug ("can't perform block_read!\n");
130                                 return (-1);
131                         }
132                         part_table = &buffer[0x1be];    /* start with partition #4 */
133                         for (j = 0; j < 4; j++) {
134                                 if ((part_table[4] == 1 ||      /* 12-bit FAT */
135                                      part_table[4] == 4 ||      /* 16-bit FAT */
136                                      part_table[4] == 6) &&     /* > 32Meg part */
137                                     part_table[0] == 0x80) {    /* bootable? */
138                                         curr_dev = i;
139                                         part_offset = part_table[11];
140                                         part_offset <<= 8;
141                                         part_offset |= part_table[10];
142                                         part_offset <<= 8;
143                                         part_offset |= part_table[9];
144                                         part_offset <<= 8;
145                                         part_offset |= part_table[8];
146                                         debug ("found partition start at %ld\n", part_offset);
147                                         return (0);
148                                 }
149                                 part_table += 16;
150                         }
151                 }
152         }
153
154         debug ("no valid devices found!\n");
155         return (-1);
156 }
157
158 int
159 do_fat_dump (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
160 {
161         __u8 block[1024];
162         int ret;
163         int bknum;
164
165         ret = 0;
166
167         if (argc != 2) {
168                 printf ("needs an argument!\n");
169                 return (0);
170         }
171
172         bknum = simple_strtoul (argv[1], NULL, 10);
173
174         if (disk_read (0, bknum, block) != 0) {
175                 printf ("Error: reading block\n");
176                 return -1;
177         }
178         printf ("FAT dump: %d\n", bknum);
179         hexdump (512, block);
180
181         return (ret);
182 }
183
184 int disk_read (__u32 startblock, __u32 getsize, __u8 *bufptr)
185 {
186         ulong tot;
187         block_dev_desc_t *dev_desc;
188
189         if (curr_dev < 0) {
190                 if (find_fat_partition () != 0)
191                         return (-1);
192         }
193
194         dev_desc = ide_get_dev (curr_dev);
195         if (!dev_desc) {
196                 debug ("couldn't get ide device\n");
197                 return (-1);
198         }
199
200         tot = dev_desc->block_read (0, startblock + part_offset,
201                                     getsize, (ulong *) bufptr);
202
203         /* should we do this here?
204            flush_cache ((ulong)buf, cnt*ide_dev_desc[device].blksz);
205          */
206
207         if (tot == getsize)
208                 return (0);
209
210         debug ("unable to read from device!\n");
211
212         return (-1);
213 }
214
215
216 static int isprint (unsigned char ch)
217 {
218         if (ch >= 32 && ch < 127)
219                 return (1);
220
221         return (0);
222 }
223
224
225 void hexdump (int cnt, unsigned char *data)
226 {
227         int i;
228         int run;
229         int offset;
230
231         offset = 0;
232         while (cnt) {
233                 printf ("%04X : ", offset);
234                 if (cnt >= 16)
235                         run = 16;
236                 else
237                         run = cnt;
238                 cnt -= run;
239                 for (i = 0; i < run; i++)
240                         printf ("%02X ", (unsigned int) data[i]);
241                 printf (": ");
242                 for (i = 0; i < run; i++)
243                         printf ("%c", isprint (data[i]) ? data[i] : '.');
244                 printf ("\n");
245                 data = &data[16];
246                 offset += run;
247         }
248 }
249 #endif  /* NOT_IMPLEMENTED_YET */
250
251 #endif  /* CFG_CMD_FAT */