From: Paul B. <pa...@co...> - 2004-09-27 13:26:32
|
I'm happy to report partial success getting ipodlinux to boot on a g4 ipod. As has been noted previously, these use a different firmware image format. Fortunately it looks like the differences are trivial. The format is the same as previous ipods, just with 512 bytes of padding added to the start of the image. I can now load modified firmware, but the memory map seems significantly different, hence "partial success". So far I've determined that main memory is at 0x1000000, on-chip ram is at 0x40000000, and the cpu id is stored at 0x60000000. Below are my changes to make_fw, and primitive attempts to get the bootloader working. I disabled most of the bootloader code as it just crashes, presumably because the address of the devices has changed. The bootloader still doesn't load the apple firmware properly. The menu works ok, but music doesn't play. I guess this means the coprocessor isn't handled properly. Paul diff -u ipodloader-src-0.3.1/loader.c my_ipodloader/loader.c --- ipodloader-src-0.3.1/loader.c 2004-03-24 18:15:44.000000000 +0000 +++ my_ipodloader/loader.c 2004-09-26 19:51:35.000000000 +0100 @@ -110,18 +136,23 @@ image_t *tblp = boot_table; void *entry; display_image(&tux_hdr, 0x0); +#if 0 init_keyboard(); imageno = key_pressed(); - +#else + imageno = 0; +#endif if (!tblp[imageno].type) imageno = 0; tblp += imageno; entry = tblp->addr + tblp->entryOffset; - if (imageno || tblp->addr != (void *)0x28000000) { - memmove16(tblp->addr, tblp->addr + tblp->devOffset - 0x4400, +#if 0 + if (imageno || tblp->addr != (void *)0x10000000) { + memmove16(tblp->addr, tblp->addr + tblp->devOffset - 0x4600, tblp->len); } +#endif return entry; } diff -u ipodloader-src-0.3.1/Makefile my_ipodloader/Makefile --- ipodloader-src-0.3.1/Makefile 2004-03-24 18:15:44.000000000 +0000 +++ my_ipodloader/Makefile 2004-09-26 03:20:35.000000000 +0100 @@ -1,6 +1,6 @@ #! /usr/bin/make -f -CROSS =arm-elf- +CROSS =arm-none-elf- AS =$(CROSS)as CC =$(CROSS)gcc diff -u ipodloader-src-0.3.1/make_fw.c my_ipodloader/make_fw.c --- ipodloader-src-0.3.1/make_fw.c 2004-03-24 18:15:44.000000000 +0000 +++ my_ipodloader/make_fw.c 2004-09-26 03:27:53.000000000 +0100 @@ -29,6 +29,13 @@ #include <unistd.h> #define TBL 0x4200 +/* Define to a nonzero value to generate firmware for a 4th generation + (clickwheel) ipod. */ +#define G4 1 + +/* Some firmwares have padding becore the actual image. */ +#define IMAGE_PADDING (G4 ? 0x200 : 0) +#define FIRST_OFFSET (TBL + 0x200 + IMAGE_PADDING) int be; @@ -96,7 +103,7 @@ " -i|-l: create new image to outfile\n" " up to 5 images, any of -i or -l allowed\n" " -i: image extracted with -e, load and entry address preserved\n" - " -l: raw image, loaded to 0x28000000, entry at 0x00000000\n" + " -l: raw image, loaded to 0x10000000, entry at 0x00000000\n" " -r: set master revision to rev (for example 210 for 2.10)\n" " may be needed if newest -e img is not the same as the flash rev\n" " ldr_img is the iPodLinux loader binary.\n" @@ -182,11 +189,14 @@ { image_t *image; unsigned char buf[512]; + unsigned off; image = (image_t *)buf; if (load_entry(image, f, TBL, idx) == -1) return -1; - if (fseek(f, image->devOffset, SEEK_SET) == -1) { + off = image->devOffset + IMAGE_PADDING; + + if (fseek(f, off, SEEK_SET) == -1) { fprintf(stderr, "fseek failed: %s\n", strerror(errno)); return -1; } @@ -196,7 +206,7 @@ fprintf(stderr, "fseek failed: %s\n", strerror(errno)); return -1; } - if (copysum(f, out, image->len, image->devOffset) == -1) + if (copysum(f, out, image->len, off) == -1) return -1; return 0; @@ -245,7 +255,7 @@ { '\0', '\0', '\0', '\0' }, // pad 0x4400, // devOffset 0, // len - 0x28000000, // addr + 0x10000000, // addr 0, // entry 0, // chksum 0, // vers @@ -307,7 +317,7 @@ } if (load_entry(images + images_done, in, 0, 0) == -1) return 1; - if (!offset) offset = 0x4400; + if (!offset) offset = FIRST_OFFSET; else offset = (offset + 0x1ff) & ~0x1ff; images[images_done].devOffset = offset; if (fseek(out, offset, SEEK_SET) == -1) { @@ -335,7 +345,7 @@ fprintf(stderr, "Cannot open linux image file %s\n", optarg); return 1; } - if (!offset) offset = 0x4400; + if (!offset) offset = FIRST_OFFSET; else offset = (offset + 0x1ff) & ~0x1ff; images[images_done] = image; images[images_done].devOffset = offset; @@ -408,10 +418,11 @@ return 1; } if (version) image.vers = version; - image.len = offset + len - 0x4400; - image.entryOffset = offset - 0x4400; - if ((image.chksum = copysum(out, NULL, image.len, 0x4400)) == -1) + image.len = offset + len - FIRST_OFFSET; + image.entryOffset = offset - FIRST_OFFSET; + if ((image.chksum = copysum(out, NULL, image.len, FIRST_OFFSET)) == -1) return 1; + if (fseek(out, 0x0, SEEK_SET) == -1) { fprintf(stderr, "fseek failed: %s\n", strerror(errno)); return 1; @@ -430,7 +441,10 @@ fprintf(stderr, "fwrite failed: %s\n", strerror(errno)); return 1; } - version = switch_32(0x0002010c); /* magic */ + if (G4) + version = switch_32(0x0003010c); /* magic */ + else + version = switch_32(0x0002010c); /* magic */ if (fwrite(&version, 4, 1, out) != 1) { fprintf(stderr, "fwrite failed: %s\n", strerror(errno)); return 1; diff -u ipodloader-src-0.3.1/startup.s my_ipodloader/startup.s --- ipodloader-src-0.3.1/startup.s 2004-03-24 18:15:44.000000000 +0000 +++ my_ipodloader/startup.s 2004-09-26 14:03:48.000000000 +0100 @@ -7,7 +7,8 @@ * published by the Free Software Foundation. */ - .equ C_PROCESSOR_ID, 0xc4000000 +/*G4HACK: .equ C_PROCESSOR_ID, 0xc4000000*/ + .equ C_PROCESSOR_ID, 0x60000000 .equ C_CPU_SLEEP, 0xca .equ C_CPU_WAKE, 0xce .equ C_CPU_ID, 0x55 |