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字樣。