aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorTom Rini2018-09-26 14:14:02 -0500
committerTom Rini2018-09-26 16:02:46 -0500
commit0ae8dcfef7c890330c62bb34c724126ffc169bef (patch)
treeaeeaa9a83efad66ca4db0b4aca2ee5cf3478728e /cmd
parentd8d81d4a5d0e5aaef5a005a357d3b9ed2b7cc4b2 (diff)
parenteaac4fb296b1899369e49d941f2c0d346c7f5c7a (diff)
downloadu-boot-0ae8dcfef7c890330c62bb34c724126ffc169bef.tar.gz
u-boot-0ae8dcfef7c890330c62bb34c724126ffc169bef.tar.xz
u-boot-0ae8dcfef7c890330c62bb34c724126ffc169bef.zip
Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot
Patch queue for efi - 2018-09-26 A lot of goodness in this release. We're *very* close to running the UEFI Shell and SCT natively. The only missing piece are HII protocols. - FAT write support (needed for SCT) - improved FAT directory support (needed for SCT) - RTC support with QEMU -M virt - Sandbox support (run UEFI binaries in Linux - yay) - Proper UTF-16 support - EFI_UNICODE_COLLATION_PROTOCOL support (for UEFI Shell) - EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL support (for UEFI Shell) - Fix window size determination - Fix Tegra by explicitly unmapping RAM - Clean up handle entanglement - Lots of generic code cleanup [trini: Fixup merge conflict in include/configs/qemu-arm.h] Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/bootefi.c187
-rw-r--r--cmd/fat.c34
2 files changed, 151 insertions, 70 deletions
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index b60c151fb4..82d755ceb3 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -49,6 +49,11 @@ efi_status_t efi_init_obj_list(void)
49 if (ret != EFI_SUCCESS) 49 if (ret != EFI_SUCCESS)
50 goto out; 50 goto out;
51 51
52 /* Initialize root node */
53 ret = efi_root_node_register();
54 if (ret != EFI_SUCCESS)
55 goto out;
56
52 /* Initialize EFI driver uclass */ 57 /* Initialize EFI driver uclass */
53 ret = efi_driver_init(); 58 ret = efi_driver_init();
54 if (ret != EFI_SUCCESS) 59 if (ret != EFI_SUCCESS)
@@ -116,32 +121,47 @@ static void set_load_options(struct efi_loaded_image *loaded_image_info,
116{ 121{
117 size_t size; 122 size_t size;
118 const char *env = env_get(env_var); 123 const char *env = env_get(env_var);
124 u16 *pos;
119 125
120 loaded_image_info->load_options = NULL; 126 loaded_image_info->load_options = NULL;
121 loaded_image_info->load_options_size = 0; 127 loaded_image_info->load_options_size = 0;
122 if (!env) 128 if (!env)
123 return; 129 return;
124 size = strlen(env) + 1; 130 size = utf8_utf16_strlen(env) + 1;
125 loaded_image_info->load_options = calloc(size, sizeof(u16)); 131 loaded_image_info->load_options = calloc(size, sizeof(u16));
126 if (!loaded_image_info->load_options) { 132 if (!loaded_image_info->load_options) {
127 printf("ERROR: Out of memory\n"); 133 printf("ERROR: Out of memory\n");
128 return; 134 return;
129 } 135 }
130 utf8_to_utf16(loaded_image_info->load_options, (u8 *)env, size); 136 pos = loaded_image_info->load_options;
137 utf8_utf16_strcpy(&pos, env);
131 loaded_image_info->load_options_size = size * 2; 138 loaded_image_info->load_options_size = size * 2;
132} 139}
133 140
134static void *copy_fdt(void *fdt) 141/**
142 * copy_fdt() - Copy the device tree to a new location available to EFI
143 *
144 * The FDT is relocated into a suitable location within the EFI memory map.
145 * An additional 12KB is added to the space in case the device tree needs to be
146 * expanded later with fdt_open_into().
147 *
148 * @fdt_addr: On entry, address of start of FDT. On exit, address of relocated
149 * FDT start
150 * @fdt_sizep: Returns new size of FDT, including
151 * @return new relocated address of FDT
152 */
153static efi_status_t copy_fdt(ulong *fdt_addrp, ulong *fdt_sizep)
135{ 154{
136 u64 fdt_size = fdt_totalsize(fdt);
137 unsigned long fdt_ram_start = -1L, fdt_pages; 155 unsigned long fdt_ram_start = -1L, fdt_pages;
156 efi_status_t ret = 0;
157 void *fdt, *new_fdt;
138 u64 new_fdt_addr; 158 u64 new_fdt_addr;
139 void *new_fdt; 159 uint fdt_size;
140 int i; 160 int i;
141 161
142 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 162 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
143 u64 ram_start = gd->bd->bi_dram[i].start; 163 u64 ram_start = gd->bd->bi_dram[i].start;
144 u64 ram_size = gd->bd->bi_dram[i].size; 164 u64 ram_size = gd->bd->bi_dram[i].size;
145 165
146 if (!ram_size) 166 if (!ram_size)
147 continue; 167 continue;
@@ -154,30 +174,37 @@ static void *copy_fdt(void *fdt)
154 * Give us at least 4KB of breathing room in case the device tree needs 174 * Give us at least 4KB of breathing room in case the device tree needs
155 * to be expanded later. Round up to the nearest EFI page boundary. 175 * to be expanded later. Round up to the nearest EFI page boundary.
156 */ 176 */
157 fdt_size += 4096; 177 fdt = map_sysmem(*fdt_addrp, 0);
178 fdt_size = fdt_totalsize(fdt);
179 fdt_size += 4096 * 3;
158 fdt_size = ALIGN(fdt_size + EFI_PAGE_SIZE - 1, EFI_PAGE_SIZE); 180 fdt_size = ALIGN(fdt_size + EFI_PAGE_SIZE - 1, EFI_PAGE_SIZE);
159 fdt_pages = fdt_size >> EFI_PAGE_SHIFT; 181 fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
160 182
161 /* Safe fdt location is at 128MB */ 183 /* Safe fdt location is at 127MB */
162 new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size; 184 new_fdt_addr = fdt_ram_start + (127 * 1024 * 1024) + fdt_size;
163 if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, 185 ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
164 EFI_RUNTIME_SERVICES_DATA, fdt_pages, 186 EFI_RUNTIME_SERVICES_DATA, fdt_pages,
165 &new_fdt_addr) != EFI_SUCCESS) { 187 &new_fdt_addr);
188 if (ret != EFI_SUCCESS) {
166 /* If we can't put it there, put it somewhere */ 189 /* If we can't put it there, put it somewhere */
167 new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size); 190 new_fdt_addr = (ulong)memalign(EFI_PAGE_SIZE, fdt_size);
168 if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, 191 ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
169 EFI_RUNTIME_SERVICES_DATA, fdt_pages, 192 EFI_RUNTIME_SERVICES_DATA, fdt_pages,
170 &new_fdt_addr) != EFI_SUCCESS) { 193 &new_fdt_addr);
194 if (ret != EFI_SUCCESS) {
171 printf("ERROR: Failed to reserve space for FDT\n"); 195 printf("ERROR: Failed to reserve space for FDT\n");
172 return NULL; 196 goto done;
173 } 197 }
174 } 198 }
175 199
176 new_fdt = (void*)(ulong)new_fdt_addr; 200 new_fdt = map_sysmem(new_fdt_addr, fdt_size);
177 memcpy(new_fdt, fdt, fdt_totalsize(fdt)); 201 memcpy(new_fdt, fdt, fdt_totalsize(fdt));
178 fdt_set_totalsize(new_fdt, fdt_size); 202 fdt_set_totalsize(new_fdt, fdt_size);
179 203
180 return new_fdt; 204 *fdt_addrp = new_fdt_addr;
205 *fdt_sizep = fdt_size;
206done:
207 return ret;
181} 208}
182 209
183static efi_status_t efi_do_enter( 210static efi_status_t efi_do_enter(
@@ -250,22 +277,27 @@ static void efi_carve_out_dt_rsv(void *fdt)
250 } 277 }
251} 278}
252 279
253static efi_status_t efi_install_fdt(void *fdt) 280static efi_status_t efi_install_fdt(ulong fdt_addr)
254{ 281{
255 bootm_headers_t img = { 0 }; 282 bootm_headers_t img = { 0 };
256 ulong fdt_pages, fdt_size, fdt_start, fdt_end; 283 ulong fdt_pages, fdt_size, fdt_start;
257 efi_status_t ret; 284 efi_status_t ret;
285 void *fdt;
258 286
287 fdt = map_sysmem(fdt_addr, 0);
259 if (fdt_check_header(fdt)) { 288 if (fdt_check_header(fdt)) {
260 printf("ERROR: invalid device tree\n"); 289 printf("ERROR: invalid device tree\n");
261 return EFI_INVALID_PARAMETER; 290 return EFI_INVALID_PARAMETER;
262 } 291 }
263 292
264 /* Prepare fdt for payload */ 293 /* Prepare fdt for payload */
265 fdt = copy_fdt(fdt); 294 ret = copy_fdt(&fdt_addr, &fdt_size);
266 if (!fdt) 295 if (ret)
267 return EFI_OUT_OF_RESOURCES; 296 return ret;
268 297
298 unmap_sysmem(fdt);
299 fdt = map_sysmem(fdt_addr, 0);
300 fdt_size = fdt_totalsize(fdt);
269 if (image_setup_libfdt(&img, fdt, 0, NULL)) { 301 if (image_setup_libfdt(&img, fdt, 0, NULL)) {
270 printf("ERROR: failed to process device tree\n"); 302 printf("ERROR: failed to process device tree\n");
271 return EFI_LOAD_ERROR; 303 return EFI_LOAD_ERROR;
@@ -279,30 +311,35 @@ static efi_status_t efi_install_fdt(void *fdt)
279 return EFI_OUT_OF_RESOURCES; 311 return EFI_OUT_OF_RESOURCES;
280 312
281 /* And reserve the space in the memory map */ 313 /* And reserve the space in the memory map */
282 fdt_start = ((ulong)fdt) & ~EFI_PAGE_MASK; 314 fdt_start = fdt_addr;
283 fdt_end = ((ulong)fdt) + fdt_totalsize(fdt);
284 fdt_size = (fdt_end - fdt_start) + EFI_PAGE_MASK;
285 fdt_pages = fdt_size >> EFI_PAGE_SHIFT; 315 fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
286 /* Give a bootloader the chance to modify the device tree */ 316
287 fdt_pages += 2;
288 ret = efi_add_memory_map(fdt_start, fdt_pages, 317 ret = efi_add_memory_map(fdt_start, fdt_pages,
289 EFI_BOOT_SERVICES_DATA, true); 318 EFI_BOOT_SERVICES_DATA, true);
319
290 return ret; 320 return ret;
291} 321}
292 322
293/* 323/**
294 * Load an EFI payload into a newly allocated piece of memory, register all 324 * do_bootefi_exec() - execute EFI binary
295 * EFI objects it would want to access and jump to it. 325 *
326 * @efi: address of the binary
327 * @device_path: path of the device from which the binary was loaded
328 * @image_path: device path of the binary
329 * Return: status code
330 *
331 * Load the EFI binary into a newly assigned memory unwinding the relocation
332 * information, install the loaded image protocol, and call the binary.
296 */ 333 */
297static efi_status_t do_bootefi_exec(void *efi, 334static efi_status_t do_bootefi_exec(void *efi,
298 struct efi_device_path *device_path, 335 struct efi_device_path *device_path,
299 struct efi_device_path *image_path) 336 struct efi_device_path *image_path)
300{ 337{
301 struct efi_loaded_image loaded_image_info = {}; 338 efi_handle_t mem_handle = NULL;
302 struct efi_object loaded_image_info_obj = {};
303 struct efi_object mem_obj = {};
304 struct efi_device_path *memdp = NULL; 339 struct efi_device_path *memdp = NULL;
305 efi_status_t ret; 340 efi_status_t ret;
341 struct efi_loaded_image_obj *image_handle = NULL;
342 struct efi_loaded_image *loaded_image_info = NULL;
306 343
307 EFIAPI efi_status_t (*entry)(efi_handle_t image_handle, 344 EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
308 struct efi_system_table *st); 345 struct efi_system_table *st);
@@ -310,16 +347,21 @@ static efi_status_t do_bootefi_exec(void *efi,
310 /* 347 /*
311 * Special case for efi payload not loaded from disk, such as 348 * Special case for efi payload not loaded from disk, such as
312 * 'bootefi hello' or for example payload loaded directly into 349 * 'bootefi hello' or for example payload loaded directly into
313 * memory via jtag/etc: 350 * memory via jtag, etc:
314 */ 351 */
315 if (!device_path && !image_path) { 352 if (!device_path && !image_path) {
316 printf("WARNING: using memory device/image path, this may confuse some payloads!\n"); 353 printf("WARNING: using memory device/image path, this may confuse some payloads!\n");
317 /* actual addresses filled in after efi_load_pe() */ 354 /* actual addresses filled in after efi_load_pe() */
318 memdp = efi_dp_from_mem(0, 0, 0); 355 memdp = efi_dp_from_mem(0, 0, 0);
319 device_path = image_path = memdp; 356 device_path = image_path = memdp;
320 efi_add_handle(&mem_obj); 357 /*
321 358 * Grub expects that the device path of the loaded image is
322 ret = efi_add_protocol(mem_obj.handle, &efi_guid_device_path, 359 * installed on a handle.
360 */
361 ret = efi_create_handle(&mem_handle);
362 if (ret != EFI_SUCCESS)
363 goto exit;
364 ret = efi_add_protocol(mem_handle, &efi_guid_device_path,
323 device_path); 365 device_path);
324 if (ret != EFI_SUCCESS) 366 if (ret != EFI_SUCCESS)
325 goto exit; 367 goto exit;
@@ -327,8 +369,10 @@ static efi_status_t do_bootefi_exec(void *efi,
327 assert(device_path && image_path); 369 assert(device_path && image_path);
328 } 370 }
329 371
330 efi_setup_loaded_image(&loaded_image_info, &loaded_image_info_obj, 372 ret = efi_setup_loaded_image(device_path, image_path, &image_handle,
331 device_path, image_path); 373 &loaded_image_info);
374 if (ret != EFI_SUCCESS)
375 goto exit;
332 376
333 /* 377 /*
334 * gd lives in a fixed register which may get clobbered while we execute 378 * gd lives in a fixed register which may get clobbered while we execute
@@ -337,9 +381,9 @@ static efi_status_t do_bootefi_exec(void *efi,
337 efi_save_gd(); 381 efi_save_gd();
338 382
339 /* Transfer environment variable bootargs as load options */ 383 /* Transfer environment variable bootargs as load options */
340 set_load_options(&loaded_image_info, "bootargs"); 384 set_load_options(loaded_image_info, "bootargs");
341 /* Load the EFI payload */ 385 /* Load the EFI payload */
342 entry = efi_load_pe(efi, &loaded_image_info); 386 entry = efi_load_pe(image_handle, efi, loaded_image_info);
343 if (!entry) { 387 if (!entry) {
344 ret = EFI_LOAD_ERROR; 388 ret = EFI_LOAD_ERROR;
345 goto exit; 389 goto exit;
@@ -347,10 +391,10 @@ static efi_status_t do_bootefi_exec(void *efi,
347 391
348 if (memdp) { 392 if (memdp) {
349 struct efi_device_path_memory *mdp = (void *)memdp; 393 struct efi_device_path_memory *mdp = (void *)memdp;
350 mdp->memory_type = loaded_image_info.image_code_type; 394 mdp->memory_type = loaded_image_info->image_code_type;
351 mdp->start_address = (uintptr_t)loaded_image_info.image_base; 395 mdp->start_address = (uintptr_t)loaded_image_info->image_base;
352 mdp->end_address = mdp->start_address + 396 mdp->end_address = mdp->start_address +
353 loaded_image_info.image_size; 397 loaded_image_info->image_size;
354 } 398 }
355 399
356 /* we don't support much: */ 400 /* we don't support much: */
@@ -360,8 +404,8 @@ static efi_status_t do_bootefi_exec(void *efi,
360 /* Call our payload! */ 404 /* Call our payload! */
361 debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); 405 debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
362 406
363 if (setjmp(&loaded_image_info.exit_jmp)) { 407 if (setjmp(&image_handle->exit_jmp)) {
364 ret = loaded_image_info.exit_status; 408 ret = image_handle->exit_status;
365 goto exit; 409 goto exit;
366 } 410 }
367 411
@@ -373,7 +417,7 @@ static efi_status_t do_bootefi_exec(void *efi,
373 417
374 /* Move into EL2 and keep running there */ 418 /* Move into EL2 and keep running there */
375 armv8_switch_to_el2((ulong)entry, 419 armv8_switch_to_el2((ulong)entry,
376 (ulong)&loaded_image_info_obj.handle, 420 (ulong)image_handle,
377 (ulong)&systab, 0, (ulong)efi_run_in_el2, 421 (ulong)&systab, 0, (ulong)efi_run_in_el2,
378 ES_TO_AARCH64); 422 ES_TO_AARCH64);
379 423
@@ -390,7 +434,7 @@ static efi_status_t do_bootefi_exec(void *efi,
390 secure_ram_addr(_do_nonsec_entry)( 434 secure_ram_addr(_do_nonsec_entry)(
391 efi_run_in_hyp, 435 efi_run_in_hyp,
392 (uintptr_t)entry, 436 (uintptr_t)entry,
393 (uintptr_t)loaded_image_info_obj.handle, 437 (uintptr_t)image_handle,
394 (uintptr_t)&systab); 438 (uintptr_t)&systab);
395 439
396 /* Should never reach here, efi exits with longjmp */ 440 /* Should never reach here, efi exits with longjmp */
@@ -398,13 +442,14 @@ static efi_status_t do_bootefi_exec(void *efi,
398 } 442 }
399#endif 443#endif
400 444
401 ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry); 445 ret = efi_do_enter(image_handle, &systab, entry);
402 446
403exit: 447exit:
404 /* image has returned, loaded-image obj goes *poof*: */ 448 /* image has returned, loaded-image obj goes *poof*: */
405 list_del(&loaded_image_info_obj.link); 449 if (image_handle)
406 if (mem_obj.handle) 450 efi_delete_handle(&image_handle->parent);
407 list_del(&mem_obj.link); 451 if (mem_handle)
452 efi_delete_handle(mem_handle);
408 453
409 return ret; 454 return ret;
410} 455}
@@ -443,7 +488,6 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
443 char *saddr; 488 char *saddr;
444 efi_status_t r; 489 efi_status_t r;
445 unsigned long fdt_addr; 490 unsigned long fdt_addr;
446 void *fdt;
447 491
448 /* Allow unaligned memory access */ 492 /* Allow unaligned memory access */
449 allow_unaligned(); 493 allow_unaligned();
@@ -464,8 +508,7 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
464 if (!fdt_addr && *argv[2] != '0') 508 if (!fdt_addr && *argv[2] != '0')
465 return CMD_RET_USAGE; 509 return CMD_RET_USAGE;
466 /* Install device tree */ 510 /* Install device tree */
467 fdt = map_sysmem(fdt_addr, 0); 511 r = efi_install_fdt(fdt_addr);
468 r = efi_install_fdt(fdt);
469 if (r != EFI_SUCCESS) { 512 if (r != EFI_SUCCESS) {
470 printf("ERROR: failed to install device tree\n"); 513 printf("ERROR: failed to install device tree\n");
471 return CMD_RET_FAILURE; 514 return CMD_RET_FAILURE;
@@ -489,8 +532,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
489#endif 532#endif
490#ifdef CONFIG_CMD_BOOTEFI_SELFTEST 533#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
491 if (!strcmp(argv[1], "selftest")) { 534 if (!strcmp(argv[1], "selftest")) {
492 struct efi_loaded_image loaded_image_info = {}; 535 struct efi_loaded_image_obj *image_handle;
493 struct efi_object loaded_image_info_obj = {}; 536 struct efi_loaded_image *loaded_image_info;
494 537
495 /* Construct a dummy device path. */ 538 /* Construct a dummy device path. */
496 bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 539 bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
@@ -498,9 +541,12 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
498 (uintptr_t)&efi_selftest); 541 (uintptr_t)&efi_selftest);
499 bootefi_image_path = efi_dp_from_file(NULL, 0, "\\selftest"); 542 bootefi_image_path = efi_dp_from_file(NULL, 0, "\\selftest");
500 543
501 efi_setup_loaded_image(&loaded_image_info, 544 r = efi_setup_loaded_image(bootefi_device_path,
502 &loaded_image_info_obj, 545 bootefi_image_path, &image_handle,
503 bootefi_device_path, bootefi_image_path); 546 &loaded_image_info);
547 if (r != EFI_SUCCESS)
548 return CMD_RET_FAILURE;
549
504 /* 550 /*
505 * gd lives in a fixed register which may get clobbered while we 551 * gd lives in a fixed register which may get clobbered while we
506 * execute the payload. So save it here and restore it on every 552 * execute the payload. So save it here and restore it on every
@@ -508,12 +554,12 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
508 */ 554 */
509 efi_save_gd(); 555 efi_save_gd();
510 /* Transfer environment variable efi_selftest as load options */ 556 /* Transfer environment variable efi_selftest as load options */
511 set_load_options(&loaded_image_info, "efi_selftest"); 557 set_load_options(loaded_image_info, "efi_selftest");
512 /* Execute the test */ 558 /* Execute the test */
513 r = efi_selftest(loaded_image_info_obj.handle, &systab); 559 r = efi_selftest(image_handle, &systab);
514 efi_restore_gd(); 560 efi_restore_gd();
515 free(loaded_image_info.load_options); 561 free(loaded_image_info->load_options);
516 list_del(&loaded_image_info_obj.link); 562 efi_delete_handle(&image_handle->parent);
517 return r != EFI_SUCCESS; 563 return r != EFI_SUCCESS;
518 } else 564 } else
519#endif 565#endif
@@ -575,6 +621,13 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path)
575 char filename[32] = { 0 }; /* dp->str is u16[32] long */ 621 char filename[32] = { 0 }; /* dp->str is u16[32] long */
576 char *s; 622 char *s;
577 623
624 /* efi_set_bootdev is typically called repeatedly, recover memory */
625 efi_free_pool(bootefi_device_path);
626 efi_free_pool(bootefi_image_path);
627 /* If blk_get_device_part_str fails, avoid duplicate free. */
628 bootefi_device_path = NULL;
629 bootefi_image_path = NULL;
630
578 if (strcmp(dev, "Net")) { 631 if (strcmp(dev, "Net")) {
579 struct blk_desc *desc; 632 struct blk_desc *desc;
580 disk_partition_t fs_partition; 633 disk_partition_t fs_partition;
diff --git a/cmd/fat.c b/cmd/fat.c
index 03de5d11af..4b9a7eaab0 100644
--- a/cmd/fat.c
+++ b/cmd/fat.c
@@ -104,6 +104,7 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
104 int ret; 104 int ret;
105 unsigned long addr; 105 unsigned long addr;
106 unsigned long count; 106 unsigned long count;
107 long offset;
107 struct blk_desc *dev_desc = NULL; 108 struct blk_desc *dev_desc = NULL;
108 disk_partition_t info; 109 disk_partition_t info;
109 int dev = 0; 110 int dev = 0;
@@ -126,9 +127,11 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
126 } 127 }
127 addr = simple_strtoul(argv[3], NULL, 16); 128 addr = simple_strtoul(argv[3], NULL, 16);
128 count = (argc <= 5) ? 0 : simple_strtoul(argv[5], NULL, 16); 129 count = (argc <= 5) ? 0 : simple_strtoul(argv[5], NULL, 16);
130 /* offset should be a hex, but "-1" is allowed */
131 offset = (argc <= 6) ? 0 : simple_strtol(argv[6], NULL, 16);
129 132
130 buf = map_sysmem(addr, count); 133 buf = map_sysmem(addr, count);
131 ret = file_fat_write(argv[4], buf, 0, count, &size); 134 ret = file_fat_write(argv[4], buf, offset, count, &size);
132 unmap_sysmem(buf); 135 unmap_sysmem(buf);
133 if (ret < 0) { 136 if (ret < 0) {
134 printf("\n** Unable to write \"%s\" from %s %d:%d **\n", 137 printf("\n** Unable to write \"%s\" from %s %d:%d **\n",
@@ -142,10 +145,35 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,
142} 145}
143 146
144U_BOOT_CMD( 147U_BOOT_CMD(
145 fatwrite, 6, 0, do_fat_fswrite, 148 fatwrite, 7, 0, do_fat_fswrite,
146 "write file into a dos filesystem", 149 "write file into a dos filesystem",
147 "<interface> <dev[:part]> <addr> <filename> [<bytes>]\n" 150 "<interface> <dev[:part]> <addr> <filename> [<bytes> [<offset>]]\n"
148 " - write file 'filename' from the address 'addr' in RAM\n" 151 " - write file 'filename' from the address 'addr' in RAM\n"
149 " to 'dev' on 'interface'" 152 " to 'dev' on 'interface'"
150); 153);
154
155static int do_fat_rm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
156{
157 return do_rm(cmdtp, flag, argc, argv, FS_TYPE_FAT);
158}
159
160U_BOOT_CMD(
161 fatrm, 4, 1, do_fat_rm,
162 "delete a file",
163 "<interface> [<dev[:part]>] <filename>\n"
164 " - delete a file from 'dev' on 'interface'"
165);
166
167static int do_fat_mkdir(cmd_tbl_t *cmdtp, int flag, int argc,
168 char * const argv[])
169{
170 return do_mkdir(cmdtp, flag, argc, argv, FS_TYPE_FAT);
171}
172
173U_BOOT_CMD(
174 fatmkdir, 4, 1, do_fat_mkdir,
175 "create a directory",
176 "<interface> [<dev[:part]>] <directory>\n"
177 " - create a directory in 'dev' on 'interface'"
178);
151#endif 179#endif