diff --git a/mshal/hal_patch_eeprom.go b/mshal/hal_patch_eeprom.go index 00dba45..bf07148 100644 --- a/mshal/hal_patch_eeprom.go +++ b/mshal/hal_patch_eeprom.go @@ -31,7 +31,9 @@ func (h *HAL) patchEepromDetectSize() (int, error) { } func (h *HAL) patchEEPROMUnlock(unlock bool) error { - if h.deviceType == 2109 { + if h.deviceType == 2107 { + return h.GPIOWrite(4, !unlock) + } else if h.deviceType == 2109 { return h.GPIOWrite(5, !unlock) } diff --git a/mshal/hal_patch_install.go b/mshal/hal_patch_install.go index bbf5d03..800080f 100644 --- a/mshal/hal_patch_install.go +++ b/mshal/hal_patch_install.go @@ -72,9 +72,9 @@ func patchTrampolineEncode(orig []byte, origAddr int, R0Value byte, hookAddr int return result } -func (h *HAL) patchTrampolineInstall(ram MemoryRegion, oldCode []byte, addr int, R0value byte, hookAddr int) error { +func (h *HAL) patchTrampolineInstall(ram MemoryRegion, replaceCode bool, origAddr int, addr int, R0value byte, hookAddr int) error { var trampoline []byte - if len(oldCode) == 0 { + if replaceCode { replaceLen := 0 var in [14]byte @@ -94,7 +94,7 @@ func (h *HAL) patchTrampolineInstall(ram MemoryRegion, oldCode []byte, addr int, trampoline = patchTrampolineEncode(in[:replaceLen], addr+replaceLen, R0value, hookAddr) } else { - trampoline = patchTrampolineEncode(oldCode, 0, R0value, hookAddr) + trampoline = patchTrampolineEncode(nil, origAddr, R0value, hookAddr) } trampolineAddr := h.patchAlloc(len(trampoline)) @@ -475,7 +475,7 @@ func (h *HAL) patchInstall() (bool, error) { return true, err } - var oldCodeIRQ []byte + nextAddr := 0 if userCodePresent { if !enableIrq || !enableNorm { return true, ErrorPatchFailed @@ -485,7 +485,7 @@ func (h *HAL) patchInstall() (bool, error) { enableNorm = true if h.deviceType == 2107 { /* If the USB IRQ patch is enabled it must call the original handler (or do everything itself) */ - oldCodeIRQ = []byte{0x02, 0x54, 0xae} + nextAddr = 0x54ae } } @@ -499,9 +499,9 @@ func (h *HAL) patchInstall() (bool, error) { } /* Install trampolines to callgate */ - if err := h.patchTrampolineInstall(ram, oldCodeIRQ, addrIrq, 0xee, h.patchCallAddrs[0]); err != nil { + if err := h.patchTrampolineInstall(ram, userCodePresent, nextAddr, addrIrq, 0xee, h.patchCallAddrs[0]); err != nil { return true, err - } else if err := h.patchTrampolineInstall(ram, nil, addrNorm, 0xef, h.patchCallAddrs[0]); err != nil { + } else if err := h.patchTrampolineInstall(ram, userCodePresent, 0, addrNorm, 0xef, h.patchCallAddrs[0]); err != nil { return true, err } diff --git a/mshal/ms213x/csum.go b/mshal/ms213x/csum.go new file mode 100644 index 0000000..c3a8a16 --- /dev/null +++ b/mshal/ms213x/csum.go @@ -0,0 +1,42 @@ +package ms213x + +import ( + "encoding/binary" + "errors" + "fmt" +) + +func calcSum(f []byte) uint16 { + var csum uint16 + for _, m := range f { + csum += uint16(m) + } + return csum +} + +func CheckImage(f []byte) error { + if len(f) < 0x30+4 { + return errors.New("file too short (hdr)") + } + + if t := binary.BigEndian.Uint16(f); t != 0x5aa5 && t != 0x6996 && t != 0x3cc3 { + return fmt.Errorf("unknown flash type: %x", t) + } + + codeLen := int(binary.BigEndian.Uint16(f[2:])) + end := 0x30 + codeLen + if len(f) < end+4 { + return errors.New("file too short (code)") + } + + hdrSum := calcSum(f[2:12]) + calcSum(f[16:0x30]) + codeSum := calcSum(f[0x30:end]) + + if hdrImg := binary.BigEndian.Uint16(f[end:]); hdrSum != hdrImg { + return fmt.Errorf("header checksum mismatch: %x != %x", hdrSum, hdrImg) + } else if codeImg := binary.BigEndian.Uint16(f[end+2:]); codeSum != codeImg { + return fmt.Errorf("code checksum mismatch: %x != %x", codeSum, codeImg) + } + + return nil +}