SNK NeoGeo X v370
SDCard0開機
由於司徒很想把NeoGeo X掌機改成Dingux系統,因為這樣就可以玩更多的模擬器,但是,司徒的NeoGeo X掌機版號是v370版本(已經被更換上Flash IC),因為只有舊版才是使用MicroSD,所以可以方便使用SDCard讀卡機做系統修改,而因為要換成Dingux系統需要修改系統,因此,除非解焊Flash元件,然後透過特殊讀寫方式更新系統,最後再焊接回原來的位置,但是,司徒手工沒有這麼強大,因此放棄這種解焊的方式,此外,由於國外網站有使用者貼出一張NeoGeo X掌機使用Dingux系統開機的照片,因此,司徒覺得它的掌機版號應該是舊版的掌機。
那如何在新版本的掌機上透過MicroSD開機呢?查看君正的資料手冊後,發現有SD card: MSC0的選項,這個選項應該就是SDCard0,而預設的開機選項則是Nand flash at CS1
後來發現國外網站有高手提供測試點位置,如下所示
司徒覺得這些測試點應該就是舊版掌機使用的MicroSD位置
接著焊接這一些接腳並使用SDCard轉接卡當作母座
UBoot程式位於sys_update_file檔案中,那該如何解開呢?可以使用國外高手提供的程式碼,如下程式
/* sys_update_file_extract version 0.1 gcc -o sys_update_file_extract sys_update_file_extract.c This will extract the sys_update_file from neo geo x into the following files uboot.bin = boot loader + partition table kernel1.bin = 1st kernel kernel2.bin = 2nd kernel rootfs.bin = partition 1, normally the root filesystem appfs.bin = partition 2, normally mounted to /usr/mtdblock3 cfgfs.bin = partition 3, normally mounted to /usr/mtdblock4 */ #include <unistd.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #define HEADER_SIZE 0x104; uint64_t get_num(FILE *in); void write_file(FILE *in, char *outfile, uint64_t offset, uint64_t length); typedef struct { uint64_t sd_offset; // sd card offset where this chunk would be written uint64_t sys_offset; // offset in sys_update_file where this chunk begins uint64_t length; // length of this chunk } chunk; int main(void) { FILE *in; int i = 0; int sysver; chunk uboot, kernel1, kernel2, rootfs, appfs, cfgfs; in = fopen("sys_update_file","r"); if(in == NULL) { printf("ERROR: unable to open sys_update_file"); exit(1); } uboot.length = get_num(in); uboot.sys_offset = HEADER_SIZE; kernel1.length = get_num(in); kernel1.sys_offset = uboot.sys_offset + uboot.length; kernel2.length = get_num(in); kernel2.sys_offset = kernel1.sys_offset + kernel1.length; rootfs.length = get_num(in); rootfs.sys_offset = kernel2.sys_offset + kernel2.length; appfs.length = get_num(in); appfs.sys_offset = rootfs.sys_offset + rootfs.length; cfgfs.length = get_num(in); cfgfs.sys_offset = appfs.sys_offset + appfs.length; sysver = get_num(in); uboot.sd_offset = get_num(in) << 20; kernel1.sd_offset = get_num(in) << 20; kernel2.sd_offset = get_num(in) << 20; rootfs.sd_offset = get_num(in) << 20; appfs.sd_offset = get_num(in) << 20; cfgfs.sd_offset = get_num(in) << 20; printf("sys_update_file version: %d\n", sysver); printf("uboot:\n sys offset: %ld\n length: %ld\n sd offset: %ld\n", uboot.sys_offset, uboot.length, uboot.sd_offset); write_file(in, "uboot.bin", uboot.sys_offset, uboot.length); printf("kernel1:\n sys offset: %ld\n length: %ld\n sd offset: %ld\n", kernel1.sys_offset, kernel1.length, kernel1.sd_offset); write_file(in, "kernel1.bin", kernel1.sys_offset, kernel1.length); printf("kernel2:\n sys offset: %ld\n length: %ld\n sd offset: %ld\n", kernel2.sys_offset, kernel2.length, kernel2.sd_offset); write_file(in, "kernel2.bin", kernel2.sys_offset, kernel2.length); printf("root fs:\n sys offset: %ld\n length: %ld\n sd offset: %ld\n", rootfs.sys_offset, rootfs.length, rootfs.sd_offset); write_file(in, "rootfs.bin", rootfs.sys_offset, rootfs.length); printf("app fs:\n sys offset: %ld\n length: %ld\n sd offset: %ld\n", appfs.sys_offset, appfs.length, appfs.sd_offset); write_file(in, "appfs.bin", appfs.sys_offset, appfs.length); printf("cfg fs:\n sys offset: %ld\n length: %ld\n sd offset: %ld\n", cfgfs.sys_offset, cfgfs.length, cfgfs.sd_offset); write_file(in, "cfgfs.bin", cfgfs.sys_offset, cfgfs.length); fclose(in); return 0; } // write out the chunk of data to the passed filename void write_file(FILE *in, char *outfile, uint64_t offset, uint64_t length) { char buffer[2048]; int size, left; FILE *out; out = fopen(outfile, "w"); if(out == NULL) { printf("ERROR: unable to open %s for writing\n", outfile); exit(1); } fseek(in, offset, SEEK_SET); left = length; while(left > 0) { size = fread(buffer, 1, (left > 2048 ? 2048 : left), in); fwrite(buffer, 1, size, out); left -= size; } fclose(out); } /* Each chunk from the header is 20 bytes long bytes 1-10 are a string + \0 thats a number bytes 11-20 are unknown, but all of them are the following in hex FF 00 90 A3 04 08 84 6E 98 BF This function returns the number from bytes 1-10 */ uint64_t get_num(FILE *in) { char buffer[20]; uint64_t value; if(fread(buffer, 1, 20, in) != 20) { printf("Error reading from file\n"); exit(0); } if(sscanf(buffer, "%ld", &value) != 1) { printf("Error parsing number\n"); exit(0); } return value; }
把編譯後的執行檔和sys_update_file放在一起,然後執行編譯後的執行檔即可做解壓縮的動作,接著使用WinHEX將uboot.bin直接Clone寫到SDCard即可,司徒目前是使用2GB SDCard做測試。
以下是開機訊息(Baudrate: 57600bps)
SD card found! init ok U-Boot 1.1.6-ga9493686 (Nov 19 2012 - 09:47:30) Board: Umido@SNK (CPU Speed 1020 MHz) DRAM: 256 MB Error: Unknown flash ID, force set to 'SST_ID_39SF040' Flash: 512 kB NAND:nand_get_flash_type: No NAND device found!!! NAND device: dev_id: 0x0000 ext_id: 0x000000 not known! nand_scan: No NAND device found!!! 0 MiB SD init ok *** Warning - MMC/SD first load, using default environment -=-=-=-= 0x8ff7f000 -=-=-=- jz4750_lcd.c 1439 usb status is 0 read vbat value is 3734 usb status is 0 SNK go go go! act8600: Write register --00000080 data: 00000024 act8600: Read register --00000081 data: 00000005 act8600: Write register --00000081 data: 00000081 LCD quick disable timeout! jz4750_lcd.c 1385 jz4750_lcd.c 1488 pix clk is 12142857 In jz4750fb_deep_set_mode pix clk is 12142857 jz4750_lcd.c 1500 LCD quick disable timeout! pix clk is 12142857 jz4750_lcd.c 1515 usb status is 0 usb status is 0 jz4750_lcd.c 1612 SD init ok
如果是從SDCard0開機,則會顯示SD card found!,反之則是顯示MMC init ok字樣。