3 * ZFS filesystem porting to Uboot by
4 * Jorgen Lundman <lundman at lundman.net>
7 * made from existing GRUB Sources by Sun, GNU and others.
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.
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.
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,
31 #include <linux/ctype.h>
32 #include <asm/byteorder.h>
33 #include <zfs_common.h>
34 #include <linux/stat.h>
37 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
41 #if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
42 #error DOS or EFI partition support must be selected
45 #define DOS_PART_MAGIC_OFFSET 0x1fe
46 #define DOS_FS_TYPE_OFFSET 0x36
47 #define DOS_FS32_TYPE_OFFSET 0x52
49 static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
51 char *filename = NULL;
54 unsigned long part = 1;
57 disk_partition_t info;
61 struct zfs_file zfile;
68 addr = simple_strtoul(argv[3], NULL, 16);
69 filename = getenv("bootfile");
72 addr_str = getenv("loadaddr");
74 addr = simple_strtoul(addr_str, NULL, 16);
76 addr = CONFIG_SYS_LOAD_ADDR;
86 count = simple_strtoul(argv[5], NULL, 16);
90 return cmd_usage(cmdtp);
94 puts("** No boot file defined **\n");
98 dev = (int)simple_strtoul(argv[2], &ep, 16);
99 zfs_dev_desc = get_dev(argv[1], dev);
100 if (zfs_dev_desc == NULL) {
101 printf("** Block device %s %d not supported\n", argv[1], dev);
107 puts("** Invalid boot device, use `dev[:part]' **\n");
110 part = simple_strtoul(++ep, NULL, 16);
114 if (get_partition_info(zfs_dev_desc, part, &info)) {
115 printf("** Bad partition %lu **\n", part);
119 if (strncmp((char *)info.type, BOOT_PART_TYPE,
120 strlen(BOOT_PART_TYPE)) != 0) {
121 printf("** Invalid partition type \"%s\" (expect \"" BOOT_PART_TYPE "\")\n",
125 printf("Loading file \"%s\" "
126 "from %s device %d:%lu %s\n",
127 filename, argv[1], dev, part, info.name);
129 printf("Loading file \"%s\" from %s device %d\n",
130 filename, argv[1], dev);
133 part_length = zfs_set_blk_dev(zfs_dev_desc, part);
134 if (part_length == 0) {
135 printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
139 vdev.part_length = part_length;
141 memset(&zfile, 0, sizeof(zfile));
142 zfile.device = &vdev;
143 if (zfs_open(&zfile, filename)) {
144 printf("** File not found %s\n", filename);
148 if ((count < zfile.size) && (count != 0))
149 zfile.size = (uint64_t)count;
151 if (zfs_read(&zfile, (char *)addr, zfile.size) != zfile.size) {
152 printf("** Unable to read \"%s\" from %s %d:%lu **\n",
153 filename, argv[1], dev, part);
160 /* Loading ok, update default load address */
163 printf("%llu bytes read\n", zfile.size);
164 sprintf(buf, "%llX", zfile.size);
165 setenv("filesize", buf);
171 int zfs_print(const char *entry, const struct zfs_dirhook_info *data)
174 data->dir ? "<DIR> " : " ",
176 return 0; /* 0 continue, 1 stop */
181 static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
183 const char *filename = "/";
185 unsigned long part = 1;
188 struct device_s vdev;
191 return cmd_usage(cmdtp);
193 dev = (int)simple_strtoul(argv[2], &ep, 16);
194 zfs_dev_desc = get_dev(argv[1], dev);
196 if (zfs_dev_desc == NULL) {
197 printf("\n** Block device %s %d not supported\n", argv[1], dev);
203 puts("\n** Invalid boot device, use `dev[:part]' **\n");
206 part = simple_strtoul(++ep, NULL, 16);
212 part_length = zfs_set_blk_dev(zfs_dev_desc, part);
213 if (part_length == 0) {
214 printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
218 vdev.part_length = part_length;
220 zfs_ls(&vdev, filename,
227 U_BOOT_CMD(zfsls, 4, 1, do_zfs_ls,
228 "list files in a directory (default /)",
229 "<interface> <dev[:part]> [directory]\n"
230 " - list files from 'dev' on 'interface' in a '/DATASET/@/$dir/'");
232 U_BOOT_CMD(zfsload, 6, 0, do_zfs_load,
233 "load binary file from a ZFS filesystem",
234 "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
235 " - load binary file '/DATASET/@/$dir/$file' from 'dev' on 'interface'\n"
236 " to address 'addr' from ZFS filesystem");