A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 230 lines 5.9 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2007 Dave Chapman 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21 22#include <stdio.h> 23#include <fcntl.h> 24#include <unistd.h> 25#include <string.h> 26 27static void int2be(unsigned int val, unsigned char* addr) 28{ 29 addr[0] = (val >> 24) & 0xff; 30 addr[1] = (val >> 16) & 0xff; 31 addr[2] = (val >> 8) & 0xff; 32 addr[3] = val & 0xFF; 33} 34 35static int le2int(unsigned char* buf) 36{ 37 int32_t res = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; 38 39 return res; 40} 41 42static char* get_modelname(int version) 43{ 44 45 switch (version >> 8) { 46 case 0x01: 47 return "1g2g"; 48 break; 49 case 0x02: 50 return "ip3g"; 51 break; 52 case 0x40: 53 return "mini"; 54 break; 55 case 0x50: 56 return "ip4g"; 57 break; 58 case 0x60: 59 return "ipco"; 60 break; 61 case 0x70: 62 return "mn2g"; 63 break; 64 case 0xc0: 65 return "nano"; 66 break; 67 case 0xb0: 68 return "ipvd"; 69 break; 70 } 71 72 return NULL; 73} 74 75static int get_modelnum(int version) 76{ 77 78 switch (version >> 8) { 79 case 0x01: 80 return 19; // "1g2g"; 81 break; 82 case 0x02: 83 return 7; // "ip3g"; 84 break; 85 case 0x40: 86 return 9; // "mini"; 87 break; 88 case 0x50: 89 return 8; // "ip4g"; 90 break; 91 case 0x60: 92 return 3; // "ipco"; 93 break; 94 case 0x70: 95 return 11; // "mn2g"; 96 break; 97 case 0xc0: 98 return 4; // "nano"; 99 break; 100 case 0xb0: 101 return 5; // "ipvd"; 102 break; 103 } 104 105 return -1; 106} 107 108 109static void dump_app(char* name, unsigned char* p, unsigned char* flash) 110{ 111 char filename[64]; 112 unsigned char header[8]; 113 unsigned int i; 114 unsigned int sum; 115 int outfile; 116 117 unsigned int unknown1; 118 unsigned int offset; 119 unsigned int length; 120 unsigned int loadaddr; 121 unsigned int unknown2; 122 unsigned int checksum; 123 unsigned int version; 124 unsigned int unknown3; 125 char* modelname; 126 127 /* Extract variables from header */ 128 unknown1 = le2int(p+0x08); 129 offset = le2int(p+0x0c); 130 length = le2int(p+0x10); 131 loadaddr = le2int(p+0x14); 132 unknown2 = le2int(p+0x18); 133 checksum = le2int(p+0x1c); 134 version = le2int(p+0x20); 135 unknown3 = le2int(p+0x24); 136 137 modelname = get_modelname(version); 138 sum = 0; 139 140 for (i = offset; i < offset+length ; i++) { 141 sum += flash[i]; 142 } 143 144 /* Display information: */ 145 printf("Image: %s\n",name); 146 printf("unknown1: %08x\n",unknown1); 147 printf("offset: %08x\n",offset); 148 printf("length: %08x\n",length); 149 printf("loadaddr: %08x\n",loadaddr); 150 printf("unknown2: %08x\n",unknown2); 151 printf("checksum: %08x (flashsplit sum: %08x)\n",checksum,sum); 152 printf("version: %08x (ipod model: %s)\n",version,modelname); 153 printf("unknown3: %08x\n",unknown3); 154 printf("\n"); 155 156 if (modelname == NULL) { 157 printf("Unknown version, not exporting to .ipod file\n"); 158 return; 159 } else if (checksum != sum) { 160 printf("Checksum mismatch, not exporting to .ipod file\n"); 161 } else { 162 sum += get_modelnum(version); 163 int2be(sum,header); 164 memcpy(header+4,modelname,4); 165 166 sprintf(filename,"%s.ipod",name); 167 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY,0666); 168 if (outfile < 0) { 169 fprintf(stderr,"[ERR] Couldn't open file %s\n",filename); 170 return; 171 } 172 173 write(outfile,header,8); 174 write(outfile,flash+offset,length); 175 close(outfile); 176 } 177 178 sprintf(filename,"%s.bin",name); 179 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY,0666); 180 if (outfile < 0) { 181 fprintf(stderr,"[ERR] Couldn't open file %s\n",filename); 182 return; 183 } 184 185 write(outfile,flash+offset,length); 186 close(outfile); 187} 188 189int main(int argc,char* argv[]) 190{ 191 int fd; 192 unsigned char buf[1024*1024]; 193 unsigned char* p; 194 195 if (argc != 2) { 196 fprintf(stderr,"Usage: flashsplit flash.bin\n"); 197 return 1; 198 } 199 200 fd=open(argv[1],O_RDONLY); 201 if (fd < 0) { 202 fprintf(stderr,"Can not open %s\n",argv[1]); 203 return 1; 204 } 205 206 read(fd,buf,sizeof(buf)); 207 close(fd); 208 209 210 p = buf + 0xffe00; /* Start of flash directory */ 211 212 while (le2int(p) != 0) { 213 if (memcmp(p,"hslfksid",8)==0) { 214 dump_app("diskmode",p,buf); 215 } else if (memcmp(p,"hslfgaid",8)==0) { 216 dump_app("diagmode",p,buf); 217 } else if (memcmp(p,"hslfogol",8)==0) { 218 dump_app("logo",p,buf); 219 } else if (memcmp(p,"hslfnacs",8)==0) { 220 dump_app("diskscan",p,buf); 221 } else if (memcmp(p,"hslfscmv",8)==0) { 222 dump_app("vmcs",p,buf); 223 } else { 224 printf("Unknown image type - %c%c%c%c%c%c%c%c\n",p[3],p[2],p[1],p[0],p[7],p[6],p[5],p[4]); 225 } 226 p += 0x28; 227 } 228 229 return 0; 230}