diff --git a/hw/application_fpga/tools/partition_table/partition_table.go b/hw/application_fpga/tools/partition_table/partition_table.go new file mode 100644 index 0000000..8975718 --- /dev/null +++ b/hw/application_fpga/tools/partition_table/partition_table.go @@ -0,0 +1,149 @@ +package main + +import ( + "encoding/binary" + "encoding/json" + "flag" + "fmt" + "io" + "os" +) + +type PartTable struct { + Header struct { + Version uint8 + } + ManagementAppData struct { + Status uint8 + Auth struct { + Nonce [16]uint8 + AuthDigest [16]uint8 + } + } + PreLoadedAppData [2]struct { + Status uint8 + Size uint32 + Auth struct { + Nonce [16]uint8 + AuthDigest [16]uint8 + } + Digest [32]uint8 + Signature [64]uint8 + } + AppStorage [4]struct { + Status uint8 + Auth struct { + Nonce [16]uint8 + AuthDigest [16]uint8 + } + AddrStart uint32 + Size uint32 + } +} + +type Flash struct { + Bitstream [0x20000]uint8 + PartitionTable PartTable + PartitionTablePadding [64*1024 - 464]uint8 + PreLoadedApp0 [0x20000]uint8 + PreLoadedApp1 [0x20000]uint8 + AppStorage [4][0x20000]uint8 + EndPadding [0x10000]uint8 +} + +func readPartTable(filename string) PartTable { + var tbl PartTable + + tblFile, err := os.Open(filename) + if err != nil { + panic(err) + } + + if err := binary.Read(tblFile, binary.LittleEndian, &tbl); err != nil { + fmt.Println("binary.Read failed:", err) + } + + tblStructLen, _ := tblFile.Seek(0, io.SeekCurrent) + fmt.Fprintf(os.Stderr, "INFO: Go partition table struct is %d byte long\n", tblStructLen) + + return tbl +} + +func readFlashDump(filename string) Flash { + var flash Flash + + flashFile, err := os.Open(filename) + if err != nil { + panic(err) + } + + if err := binary.Read(flashFile, binary.LittleEndian, &flash); err != nil { + fmt.Println("binary.Read failed:", err) + } + + flashStructLen, _ := flashFile.Seek(0, io.SeekCurrent) + fmt.Fprintf(os.Stderr, "INFO: Go flash table struct is %d Mbyte long\n", flashStructLen/1024/1024) + + return flash +} + +func printPartTableJson(tbl PartTable) { + partTableJSON, err := json.MarshalIndent(tbl, "", " ") + if err != nil { + panic(err) + } + fmt.Printf("%s\n", string(partTableJSON)) +} + +func printPartTableCondensed(tbl PartTable) { + fmt.Printf("Header\n") + fmt.Printf(" Version : %d\n", tbl.Header.Version) + fmt.Printf("Management App\n") + fmt.Printf(" Status : %d\n", tbl.ManagementAppData.Status) + fmt.Printf(" Auth.Nonce : %x\n", tbl.ManagementAppData.Auth.Nonce) + fmt.Printf(" Auth.AuthDigest : %x\n", tbl.ManagementAppData.Auth.AuthDigest) + + for i, appData := range tbl.PreLoadedAppData { + fmt.Printf("Preloaded App %d\n", i) + fmt.Printf(" Status : %d\n", appData.Status) + fmt.Printf(" Size : %d\n", appData.Size) + fmt.Printf(" Auth.Nonce : %x\n", appData.Auth.Nonce) + fmt.Printf(" Auth.AuthDigest : %x\n", appData.Auth.AuthDigest) + fmt.Printf(" Digest : %x\n", appData.Digest[:16]) + fmt.Printf(" %x\n", appData.Digest[16:]) + fmt.Printf(" Signature : %x\n", appData.Signature[:16]) + fmt.Printf(" %x\n", appData.Signature[16:32]) + fmt.Printf(" %x\n", appData.Signature[32:48]) + fmt.Printf(" %x\n", appData.Signature[48:]) + } +} + +func main() { + filename := "" + json := false + flash := false + + flag.StringVar(&filename, "i", "", "Partition table binary dump file.") + flag.BoolVar(&json, "j", false, "Print partition table in JSON format.") + flag.BoolVar(&flash, "f", false, "Treat input file as a dump of the entire flash memory.") + flag.Parse() + + if filename == "" { + flag.Usage() + os.Exit(1) + } + + var tbl PartTable + + if flash { + tbl = readFlashDump(filename).PartitionTable + } else { + tbl = readPartTable(filename) + } + + if json { + printPartTableJson(tbl) + } else { + printPartTableCondensed(tbl) + } +}