]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_zfs.c
x86: Add CBMEM console driver for coreboot
[karo-tx-uboot.git] / common / cmd_zfs.c
1 /*
2  *
3  * ZFS filesystem porting to Uboot by
4  * Jorgen Lundman <lundman at lundman.net>
5  *
6  * zfsfs support
7  * made from existing GRUB Sources by Sun, GNU and others.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  *
24  */
25
26 #include <common.h>
27 #include <part.h>
28 #include <config.h>
29 #include <command.h>
30 #include <image.h>
31 #include <linux/ctype.h>
32 #include <asm/byteorder.h>
33 #include <zfs_common.h>
34 #include <linux/stat.h>
35 #include <malloc.h>
36
37 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
38 #include <usb.h>
39 #endif
40
41 #if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
42 #error DOS or EFI partition support must be selected
43 #endif
44
45 #define DOS_PART_MAGIC_OFFSET   0x1fe
46 #define DOS_FS_TYPE_OFFSET      0x36
47 #define DOS_FS32_TYPE_OFFSET    0x52
48
49 static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
50 {
51         char *filename = NULL;
52         int dev;
53         int part;
54         ulong addr = 0;
55         disk_partition_t info;
56         block_dev_desc_t *dev_desc;
57         char buf[12];
58         unsigned long count;
59         const char *addr_str;
60         struct zfs_file zfile;
61         struct device_s vdev;
62
63         if (argc < 3)
64                 return CMD_RET_USAGE;
65
66         count = 0;
67         addr = simple_strtoul(argv[3], NULL, 16);
68         filename = getenv("bootfile");
69         switch (argc) {
70         case 3:
71                 addr_str = getenv("loadaddr");
72                 if (addr_str != NULL)
73                         addr = simple_strtoul(addr_str, NULL, 16);
74                 else
75                         addr = CONFIG_SYS_LOAD_ADDR;
76
77                 break;
78         case 4:
79                 break;
80         case 5:
81                 filename = argv[4];
82                 break;
83         case 6:
84                 filename = argv[4];
85                 count = simple_strtoul(argv[5], NULL, 16);
86                 break;
87
88         default:
89                 return cmd_usage(cmdtp);
90         }
91
92         if (!filename) {
93                 puts("** No boot file defined **\n");
94                 return 1;
95         }
96
97         part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
98         if (part < 0)
99                 return 1;
100
101         dev = dev_desc->dev;
102         printf("Loading file \"%s\" from %s device %d%c%c\n",
103                 filename, argv[1], dev,
104                 part ? ':' : ' ', part ? part + '0' : ' ');
105
106         zfs_set_blk_dev(dev_desc, &info);
107         vdev.part_length = info.size;
108
109         memset(&zfile, 0, sizeof(zfile));
110         zfile.device = &vdev;
111         if (zfs_open(&zfile, filename)) {
112                 printf("** File not found %s\n", filename);
113                 return 1;
114         }
115
116         if ((count < zfile.size) && (count != 0))
117                 zfile.size = (uint64_t)count;
118
119         if (zfs_read(&zfile, (char *)addr, zfile.size) != zfile.size) {
120                 printf("** Unable to read \"%s\" from %s %d:%d **\n",
121                            filename, argv[1], dev, part);
122                 zfs_close(&zfile);
123                 return 1;
124         }
125
126         zfs_close(&zfile);
127
128         /* Loading ok, update default load address */
129         load_addr = addr;
130
131         printf("%llu bytes read\n", zfile.size);
132         sprintf(buf, "%llX", zfile.size);
133         setenv("filesize", buf);
134
135         return 0;
136 }
137
138
139 int zfs_print(const char *entry, const struct zfs_dirhook_info *data)
140 {
141         printf("%s %s\n",
142                    data->dir ? "<DIR> " : "              ",
143                    entry);
144         return 0; /* 0 continue, 1 stop */
145 }
146
147
148
149 static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
150 {
151         const char *filename = "/";
152         int part;
153         block_dev_desc_t *dev_desc;
154         disk_partition_t info;
155         struct device_s vdev;
156
157         if (argc < 2)
158                 return cmd_usage(cmdtp);
159
160         if (argc == 4)
161                 filename = argv[3];
162
163         part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
164         if (part < 0)
165                 return 1;
166
167         zfs_set_blk_dev(dev_desc, &info);
168         vdev.part_length = info.size;
169
170         zfs_ls(&vdev, filename,
171                    zfs_print);
172
173         return 0;
174 }
175
176
177 U_BOOT_CMD(zfsls, 4, 1, do_zfs_ls,
178                    "list files in a directory (default /)",
179                    "<interface> <dev[:part]> [directory]\n"
180                    "      - list files from 'dev' on 'interface' in a '/DATASET/@/$dir/'");
181
182 U_BOOT_CMD(zfsload, 6, 0, do_zfs_load,
183                    "load binary file from a ZFS filesystem",
184                    "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
185                    "      - load binary file '/DATASET/@/$dir/$file' from 'dev' on 'interface'\n"
186                    "             to address 'addr' from ZFS filesystem");