SNK NeoGeo X v370

SDCard0開機


由於司徒很想把NeoGeo X掌機改成一般Dingux系統,因為這樣就可以玩更多的模擬器遊戲,但是,司徒的NeoGeo X掌機版號是v370版本,因此已經被更換上Flash Memory IC元件,因為只有舊版掌機才是使用MicroSD代替Flash Memory IC元件,所以可以使用SDCard讀卡機做內部系統檔案修改,可以很輕鬆達到更換新系統的目的,因為要換成Dingux系統需要修改系統的內部檔案,因此,新版的Flash Memory元件是無法做到這一點的,除非解焊Flash Memory元件,然後透過特殊讀寫方式更新系統,最後再銲接回去原來的位置,但是,司徒手工沒有這麼強大,因此放棄這種解焊的方式,此外,由於國外網站有使用者貼出一張NeoGeo X掌機使用Dingux系統開機的照片,因此,司徒覺得它的掌機版號應該是舊版的掌機。

那如何在新版本的掌機上透過MicroSD開機呢?查看君正的資料手冊後,發現有SD card: MSC0的選項,這個選項應該就是SDCard-0,而預設的開機選項則是Nand flash at CS1,但是,司徒感覺有一個怪怪的地方,那就是舊版使用MicroSD元件,而新版則是使用Flash Memory IC元件,但是,銲接的位置竟然都是位於同一個地方,這下更是讓司徒搞混了。

後來發現國外網站有高手提供測試點位置,如下所示

司徒覺得這些測試點應該就是舊版掌機使用的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

如果是從SDCard-0開機,則會顯示SD card found!,反之則是顯示MMC init ok字樣。


返回上一頁