Last active
December 21, 2015 06:19
-
-
Save quarnster/6263313 to your computer and use it in GitHub Desktop.
Go code for dumping the raw nandflash data from Boxeebox's /dev/spectra
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// GOOS=linux GOARCH=386 go build flash.go && ftp -u boxeebox:/tmp/flash flash | |
package main | |
import ( | |
"fmt" | |
"log" | |
"os" | |
"syscall" | |
"unsafe" | |
) | |
type ( | |
BLOCKNODE uint32 | |
PAGENUMTYPE uint16 | |
PAGESIZETYPE uint16 | |
BLOCKSIZETYPE uint32 | |
ADDRESSTYPE uintptr | |
BOOT_BLOCKTABLE_IO_CMD struct { | |
btEntrySizeInBits byte | |
btEntryNum uint16 | |
AddrInRam ADDRESSTYPE | |
} | |
BOOT_BLOCKTABLE_INFO struct { | |
bt_sig [4]byte | |
nSpareSkipByteInZone1, nSpareSkipByteInZone0, reserve3, btEntrySizeInBits byte | |
btEntryNum, btOffsetInBytes, md5OffsetInBytes, md5SizeInBytes uint16 | |
} | |
SPEC_IO_CMD struct { | |
NumPagesToTransfer uint32 | |
AddrInRam ADDRESSTYPE | |
StartBlockNum BLOCKNODE | |
StartPageNum uint16 | |
} | |
DEVICE_INFO struct { | |
wDeviceMaker uint16 | |
wDeviceType uint32 | |
wSpectraStartBlock BLOCKNODE | |
wSpectraEndBlock BLOCKNODE | |
wBlockNum BLOCKNODE | |
wTotalBlocks BLOCKNODE | |
wPagesPerBlock PAGENUMTYPE | |
wPageSize PAGESIZETYPE | |
wPageDataSize PAGESIZETYPE | |
wPageSpareSize PAGESIZETYPE | |
wNumPageSpareFlag uint16 | |
wECCBytesPerSector uint16 | |
wBlockSize BLOCKSIZETYPE | |
wBlockDataSize BLOCKSIZETYPE | |
wDataBlockNum BLOCKNODE | |
bPlaneNum byte | |
wDeviceMainAreaSize uint16 | |
wDeviceSpareAreaSize uint16 | |
wDevicesConnected uint16 | |
wDeviceWidth uint16 | |
wHWRevision uint16 | |
wHWFeatures uint16 | |
wONFIDevFeatures uint16 | |
wONFIOptCommands uint16 | |
wONFITimingMode uint16 | |
wONFIPgmCacheTimingMode uint16 | |
MLCDevice uint16 | |
wSpareSkipBytes uint16 | |
} | |
) | |
const ( | |
GLOB_SBD_IOCTL_RD_MAIN = 0x8810 + iota | |
GLOB_SBD_IOCTL_WR_MAIN | |
GLOB_SBD_IOCTL_ERASE | |
GLOB_SBD_IOCTL_RD_ID | |
GLOB_SBD_IOCTL_CHK_BADBLK | |
GLOB_SBD_IOCTL_RD_MAIN_SPARE_RAW | |
GLOB_SBD_IOCTL_WR_MAIN_SPARE_RAW | |
) | |
const ( | |
GLOB_SBD_IOCTL_ERASE_RAW = 0x9910 + iota | |
GLOB_SBD_IOCTL_RD_BT | |
GLOB_SBD_IOCTL_CREATE_BT_DUMMY | |
GLOB_SBD_IOCTL_CREATE_BT_BYERASE | |
GLOB_SBD_IOCTL_CREATE_BT_BYMARKER | |
GLOB_SBD_IOCTL_ERASE_BYMARKER | |
) | |
func ioctl(device int, cmd uintptr, data unsafe.Pointer) (int, error) { | |
a, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(device), cmd, uintptr(data)) | |
var err error | |
if errno != 0 { | |
err = errno | |
} | |
return int(a), err | |
} | |
func main() { | |
var ( | |
id DEVICE_INFO | |
read SPEC_IO_CMD | |
) | |
device, err := syscall.Open("/dev/spectra", syscall.O_RDONLY, 0) | |
if err != nil || device < 0 { | |
log.Fatalf("Device is negative: %d, %s", device, err) | |
} | |
defer syscall.Close(device) | |
log.Println("device:", device) | |
if _, err := ioctl(device, GLOB_SBD_IOCTL_RD_ID, unsafe.Pointer(&id)); err != nil { | |
log.Fatalln(err) | |
} | |
log.Printf("%+v", id) | |
data := make([]byte, int(id.wPageSize)*int(id.wPagesPerBlock)) | |
read.StartBlockNum = 8 | |
read.AddrInRam = ADDRESSTYPE(unsafe.Pointer(&data[0])) | |
read.NumPagesToTransfer = uint32(id.wPagesPerBlock) | |
log.Println(ioctl(device, GLOB_SBD_IOCTL_RD_MAIN, unsafe.Pointer(&read))) | |
log.Printf("%+v", *(*BOOT_BLOCKTABLE_INFO)(unsafe.Pointer(&data[32]))) | |
for read.StartBlockNum = 0; read.StartBlockNum < id.wBlockNum; read.StartBlockNum++ { | |
func() { | |
fn := fmt.Sprintf("/tmp/mnt/sdcard/dump/dump%d.dat", read.StartBlockNum) | |
log.Printf("dumping block %d to %s", read.StartBlockNum, fn) | |
f, err := os.Create(fn) | |
if err != nil { | |
log.Fatalln(err) | |
} | |
defer f.Close() | |
if i, err := ioctl(device, GLOB_SBD_IOCTL_RD_MAIN, unsafe.Pointer(&read)); i == -1 || err != nil { | |
log.Fatalf("RD_MAIN ioctl failed: %d, %s", i, err) | |
} else { | |
// log.Printf("%d %+v", i, read) | |
f.Write(data) | |
} | |
}() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment