Information/PPCFlashROM
This article originally
based on work done by Frontalot
at Linkstationwiki.org
Contents
Flash ROM analysis
Device | Major | Minor | End | Size | Function |
/dev/fl0 | 250 | 0 | 0xFFF80000 | 512KB | Stores configuration files as conf_save.tar.gz (written by as_flash). |
/dev/fl1 | 250 | 1 | 0xFFC00000 | 3MB | Stores firmimg.bin (firminfo.txt, vmlinux.gz, ramdisk.image.gz). |
/dev/fl2 | 250 | 2 | 0xFFF00000 | 448KB | Boot loader (bootcode.bin). |
/dev/fl3 | 250 | 3 | 0xFFF70000 | 64KB | Boot status ("OKOK" - normal boot, "NGNG" - EM mode). |
/dev/fl4 | 250 | 4 | 0xFFC00000 | 4MB | Entire Flash ROM (in the order fl1, fl2, fl3, fl0). |
Note: If the flash devices do not already exist, they can easily be created by mknod:
mknod /dev/fl0 b 250 0 mknod /dev/fl1 b 250 1 mknod /dev/fl2 b 250 2 mknod /dev/fl3 b 250 3 mknod /dev/fl4 b 250 4
/dev/fl0
Contents of conf_save.tar.gz:
etc/network/interfaces etc/samba/ etc/samba/smbusers etc/samba/smb.conf etc/samba/lmhosts etc/samba/smbpasswd etc/samba/secrets.tdb etc/samba/smb.conf.bak etc/atalk/ etc/atalk/atalkd.conf etc/atalk/AppleVolumes.default etc/atalk/AppleVolumes.system etc/atalk/afpd.conf etc/atalk/config etc/atalk/papd.conf etc/atalk/config.papd etc/melco/ etc/melco/timer_sleep etc/melco/timer_backup etc/melco/timer_backup.cron etc/melco/timer_status etc/melco/info etc/melco/shareinfo etc/melco/usercount etc/melco/userinfo etc/melco/printer etc/melco/groupinfo etc/melco/ver etc/melco/pcast_mp2000 etc/melco/ftpstatus etc/melco/pdcuserinfo etc/melco/pdcuserinfo.base etc/melco/backup_error_status etc/melco/timer_backup_folder etc/melco/ntp etc/melco/ntp_result etc/melco/pdcgroupinfo etc/melco/shareinfo.bak etc/passwd etc/group etc/hosts www/.htpasswd www/cgi-bin/.htpasswd www/script/.htpasswd etc/ap_servd.log etc/printcap etc/pcast/pcastd.conf
You can read and write conf_save.tar.gz to and from /dev/fl0 by using /usr/bin/as_flash:
as_flash [device] [add|del|get|init] [options] add -n <filename> add file image to end of flash del [-n <filename>|-i <block number>] delete Entered file name or block number of block data from flash get [-n <filename>|-i <block number>] [--output <filename>] read Entered file name or block number of block data from flash, and store output filename init clear device by zero
For example:
as_flash /dev/fl0</ get -n /tmp/conf_save.tar.gz --output /tmp/conf_save.tar.gz
There is a "hidden" feature to list the contents of the flash bank:
as_flash /dev/fl0 list
/dev/fl1
firmimg.bin contains 3 parts:
- firminfo.txt - The 108 byte firmware header.
- vmlinux.gz - The kernel.
- ramdisk.image.gz - The ramdisk.
firminfo.txt:
Offset | Size | Field | Content - 1.47 | Content - 1.51 |
0 | 4 | Version | 1 | 1 |
4 | 4 | Firmware ID | 3 | 3 |
8 | 32 | Firmware Name (padding with 0x00) | HD-HLAN(HIDETADA) | HD-HLAN(HIDETADA) |
40 | 32 | Sub Version (padding with 0x00) | FLASH 1.1 | FLASH 1.4 |
72 | 2 | Major Version | 1 | 1 |
74 | 2 | Minor Version | 5 | 6 |
76 | 2 | Build Number | 0 | 0 |
78 | 6 | Build Date | 2004/5/21 13:41:0 | 2005/2/25 19:31:10 |
84 | 4 | firmimg.bin size | 2879996 bytes | 2933224 bytes |
88 | 4 | Checksum | 658752272 | 4191046432 |
92 | 4 | vmlinux.gz offset | 108 bytes | 108 bytes |
96 | 4 | vmlinux.gz size | 838590 bytes | 846428 bytes |
100 | 4 | ramdisk.image.gz offset | 838698 bytes | 846536 bytes |
104 | 4 | ramdisk.image.gz size | 2041298 bytes | 2086688 bytes |
The following script analyzes firmimg.bin and provides the preceding information:
#! /usr/bin/perl read(STDIN, $tmp, 108, 0); @tmp = unpack("LLA32A32SSSC6LLLLLL", $tmp); print "Version ". $tmp[0]."\n"; print "Firmware ID ". $tmp[1]."\n"; print "Firmware Name ". $tmp[2]."\n"; print "Sub Version ". $tmp[3]."\n"; print "Major Version ". $tmp[4]."\n"; print "Minor Version ". $tmp[5]."\n"; print "Build Number ". $tmp[6]."\n"; printf "Build Date %d/%d/%d %d:%d:%d\n", $tmp[7] + 1900, $tmp[8], $tmp[9], $tmp[10], $tmp[11], $tmp[12]; print "firmimg.bin size ". $tmp[13]."\n"; print "Checksum ". $tmp[14]."\n"; print "vmlinux.gz offset ". $tmp[15]."\n"; print "vmlinux.gz size ". $tmp[16]."\n"; print "ramdisk.image.gz offset ". $tmp[17]."\n"; print "ramdisk.image.gz size ". $tmp[18]."\n";
The script can read the firmware information directly from the flash ROM:
./showflash.pl < /dev/fl1
The script also can be used to read the firmware information from firmimg.bin:
./showflash.pl < firmimg.bin
You can extract firmimg.bin from <tt>/dev/fl1 by using head:
head -c 2879996 /dev/fl1 > firmimg.bin
firminfo.txt, vmlinux.gz, and ramdisk.image.gz can be extracted from firmimg.bin:
head -c 108 firmimg.bin > firminfo.txt tail -c 2879888 firmimg.bin > temp; head -c 838590 temp > vmlinux.gz; rm temp tail -c 2041298 firmimg.bin > ramdisk.image.gz
vmlinux.gz:
Linux kernel.
ramdisk.image.gz:
You can mount the ramdisk as follows:
mount ramdisk.image /mnt/ramdisk -o loop
Raw listing of 1.47 ramdisk or 1.51 ramdisk contents.
/dev/fl2
Contains bootcode.bin (created by "make zImage")
/dev/fl3
Contains boot status ("OKOK" - normal boot, "NGNG" - EM mode).
Normal boot
0000000 4f4b 4f4b 4f4b 4f4b 4f4b 4f4b 4f4b 4f4b O K O K O K O K O K O K O K O K * 0000400 ffff ffff ffff ffff ffff ffff ffff ffff 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 * 0200000
EM mode:
0000000 4e47 4e47 4e47 4e47 4e47 4e47 4e47 4e47 N G N G N G N G N G N G N G N G * 0000400 ffff ffff ffff ffff ffff ffff ffff ffff 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 377 * 0200000
To read the boot status:
od -xc /dev/fl3
You can change the boot status by using write_ng and write_ok. To change the boot status to normal:
write_ok
To change the boot status to EM mode:
write_ng
Be very careful when changing the boot status to EM mode! You can easily lock yourself out of the LinkStation and possibly brick the unit. Always change the boot status to normal before rebooting.
Some of this information courtesy of http://www.yamasita.jp/linkstation.en/index.html.