A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

FS#13184: Support 2048 byte sectors and images without bootloader in ipod_fw

(From Stefan Ott)

I wrote a little patch for ipod_fw.c that allows me to create bootable
images for the iPod video without using any external software.

The patch adds two new options:

- The -s option can now be used to specify the sector size in blocks (typically 512 or 2048) when generating an image.
- The -n option can be used to create an image without a boot loader

Change-Id: I35ebcd19ba1491bba76dfc8011e5a856108bb9ad

+32 -17
+32 -17
tools/ipod_fw.c
··· 110 110 { 111 111 printf("Usage: ipod_fw [-h]\n" 112 112 " ipod_fw [-v] -o outfile -e img_no fw_file\n" 113 - " ipod_fw [-v] -g gen [-r rev] -o outfile [-i img_from_-e]* [-l raw_img]* ldr_img\n\n" 113 + " ipod_fw [-v] -g gen [-r rev] [-s size] -o outfile [-i img_from_-e]* [-l raw_img]* ldr_img\n\n" 114 114 " -g: set target ipod generation, valid options are: 1g, 2g, 3g\n" 115 115 " 4g, 5g, scroll, touch, dock, mini, photo, color, nano and video\n" 116 116 " -e: extract the image at img_no in boot table to outfile\n" ··· 124 124 " may be needed if newest -e img is not the same as the flash rev\n" 125 125 " ldr_img is the iPodLinux loader binary.\n" 126 126 " first image is loaded by default, 2., 3., 4. or 5. loaded if\n" 127 - " rew, menu, play or ff is hold while booting\n\n" 127 + " rew, menu, play or ff is hold while booting\n" 128 + " -n: do not add a boot loader (ldr_img)\n" 129 + " -s: set sector size in bytes (default is 512)\n\n" 128 130 " -v: verbose\n\n" 129 131 " This program is used to create a bootable ipod image.\n\n"); 130 132 } ··· 339 341 int images_done = 0; 340 342 unsigned version = 0, offset = 0, len = 0; 341 343 int needs_rcsc = 0; 344 + int no_boot = 0; 342 345 343 346 test_endian(); 344 347 345 348 /* parse options */ 346 349 opterr = 0; 347 - while ((c = getopt(argc, argv, "3hve:o:i:l:r:g:")) != -1) 350 + while ((c = getopt(argc, argv, "3hve:o:i:l:nr:g:s:")) != -1) 348 351 switch (c) { 349 352 case 'h': 350 353 if (verbose || in || out || images_done || ext) { ··· 471 474 images_done++; 472 475 fclose(in); 473 476 break; 477 + case 'n': 478 + no_boot = 1; 479 + break; 474 480 case 'r': 475 481 if (ext) { 476 482 usage(); ··· 478 484 } 479 485 version = strtol(optarg, NULL, 16); 480 486 break; 487 + case 's': 488 + sectorsize = atoi(optarg); 489 + break; 481 490 case '?': 482 491 fprintf(stderr, "invalid option -%c specified\n", optopt); 483 492 usage(); ··· 488 497 return 1; 489 498 } 490 499 491 - if (argc - optind != 1) { 500 + if ((argc - optind != 1) && !no_boot) { 492 501 usage(); 493 502 return 1; 494 503 } ··· 528 537 fprintf(stderr, "no images specified!\n"); 529 538 return 1; 530 539 } 531 - if ((in = fopen(argv[optind], "rb")) == NULL) { 532 - fprintf(stderr, "Cannot open loader image file %s\n", argv[optind]); 533 - return 1; 534 - } 535 - offset = (offset + 0x1ff) & ~0x1ff; 536 - if ((len = lengthof(in)) == -1) 537 - return 1; 538 - if (fseek(out, offset, SEEK_SET) == -1) { 539 - fprintf(stderr, "fseek failed: %s\n", strerror(errno)); 540 - return 1; 540 + if (!no_boot) 541 + { 542 + if ((in = fopen(argv[optind], "rb")) == NULL) { 543 + fprintf(stderr, "Cannot open loader image file %s\n", argv[optind]); 544 + return 1; 545 + } 546 + offset = (offset + 0x1ff) & ~0x1ff; 547 + if ((len = lengthof(in)) == -1) 548 + return 1; 549 + if (fseek(out, offset, SEEK_SET) == -1) { 550 + fprintf(stderr, "fseek failed: %s\n", strerror(errno)); 551 + return 1; 552 + } 553 + if (copysum(in, out, len, 0) == -1) 554 + return 1; 541 555 } 542 - if (copysum(in, out, len, 0) == -1) 543 - return 1; 544 556 for (i=0; i < images_done; i++) { 545 557 if (images[i].vers > image.vers) image.vers = images[i].vers; 546 558 if (write_entry(images+i, out, offset+0x0100, i) == -1) ··· 548 560 } 549 561 if (version) image.vers = version; 550 562 image.len = offset + len - FIRST_OFFSET; 551 - image.entryOffset = offset - FIRST_OFFSET; 563 + if (!no_boot) 564 + { 565 + image.entryOffset = offset - FIRST_OFFSET; 566 + } 552 567 image.devOffset = (sectorsize==512 ? 0x4400 : 0x4800); 553 568 if ((image.chksum = copysum(out, NULL, image.len, FIRST_OFFSET)) == -1) 554 569 return 1;