// MTBoss: MT6261 firmware management application // with zero DA required // Created by Luxferre in 2026, released into the public domain package main import ( "bytes" "crypto/md5" "encoding/binary" "encoding/hex" "flag" "fmt" "os" "strings" "time" "go.bug.st/serial" ) // ==================== REGISTERS & BITS ==================== const ( SFI_BASE = 0xA0140000 SFI_MAC_CTL = SFI_BASE + 0x0000 SFI_DIRECT_CTL = SFI_BASE + 0x0004 SFI_MISC_CTL = SFI_BASE + 0x0008 SFI_MAC_OUTL = SFI_BASE + 0x0010 SFI_MAC_INL = SFI_BASE + 0x0014 SFI_MISC_CTL3 = SFI_BASE + 0x0044 SFI_GPRAM = SFI_BASE + 0x0800 SFI_WIP = 1 << 0 SFI_WIP_READY = 1 << 1 SFI_TRIG = 1 << 2 SFI_MAC_EN = 1 << 3 SFI_MAC_SEL = 1 << 28 BOOT_ENG_BASE = 0xA0510000 FLASH_SIZE_4MB = 0x400000 // 4MB (4,194,304 bytes) FLASH_PAGE_SIZE = 0x100 // 256 bytes FLASH_SECTOR_SZ = 0x1000 // 4KB SR_WIP = 0x01 SR_WEL = 0x02 SR_BP0 = 0x04 SR_BP1 = 0x08 SR_BP2 = 0x10 SR_BP3 = 0x20 ) // ==================== HELPER PARSER ==================== func parseSizeOrOffset(valStr string) (uint64, error) { valStr = strings.TrimSpace(valStr) if valStr == "" { return 0, fmt.Errorf("empty string") } multiplier := uint64(1) upper := strings.ToUpper(valStr) if strings.HasSuffix(upper, "MIB") || strings.HasSuffix(upper, "MB") { multiplier = 1024 * 1024 valStr = valStr[:len(valStr)-2] if strings.HasSuffix(strings.ToUpper(valStr), "I") { valStr = valStr[:len(valStr)-1] } } else if strings.HasSuffix(upper, "M") { multiplier = 1024 * 1024 valStr = valStr[:len(valStr)-1] } else if strings.HasSuffix(upper, "KIB") || strings.HasSuffix(upper, "KB") { multiplier = 1024 valStr = valStr[:len(valStr)-2] if strings.HasSuffix(strings.ToUpper(valStr), "I") { valStr = valStr[:len(valStr)-1] } } else if strings.HasSuffix(upper, "K") { multiplier = 1024 valStr = valStr[:len(valStr)-1] } valStr = strings.TrimSpace(valStr) var val uint64 var err error if strings.HasPrefix(valStr, "0x") || strings.HasPrefix(valStr, "0X") { _, err = fmt.Sscanf(valStr, "0x%x", &val) } else { _, err = fmt.Sscanf(valStr, "%d", &val) } if err != nil { return 0, err } return val * multiplier, nil } // ==================== MTBOSS STRUCT ==================== type MTBoss struct { port serial.Port portName string chipID uint16 } func NewMTBoss(portName string) (*MTBoss, error) { flasher := &MTBoss{portName: portName} if err := flasher.connectPort(); err != nil { return nil, err } return flasher, nil } func (f *MTBoss) connectPort() error { var targetPort string if f.portName == "" || f.portName == "auto" { ports, err := serial.GetPortsList() if err == nil { for _, p := range ports { if strings.Contains(p, "ttyUSB") || strings.Contains(p, "ttyACM") || strings.Contains(p, "COM") { targetPort = p break } } } if targetPort == "" { targetPort = "/dev/ttyUSB0" } } else { targetPort = f.portName } fmt.Printf("Connecting to serial port %s at 115200 baud (RTS/CTS enabled)...\n", targetPort) mode := &serial.Mode{ BaudRate: 115200, DataBits: 8, Parity: serial.NoParity, StopBits: serial.OneStopBit, } start := time.Now() for time.Since(start) < 10*time.Minute { p, err := serial.Open(targetPort, mode) if err == nil { // Enable RTSCTS hardware flow control _ = p.SetRTS(true) _ = p.SetDTR(true) f.port = p f.portName = targetPort return nil } // Also scan for any new port if set to auto if f.portName == "auto" { ports, _ := serial.GetPortsList() for _, pName := range ports { if strings.Contains(pName, "ttyUSB") || strings.Contains(pName, "ttyACM") { p, err := serial.Open(pName, mode) if err == nil { _ = p.SetRTS(true) _ = p.SetDTR(true) f.port = p f.portName = pName return nil } } } } time.Sleep(50 * time.Millisecond) } return fmt.Errorf("timeout waiting for serial port %s", targetPort) } func (f *MTBoss) Close() { if f.port != nil { _ = f.port.Close() } } // ==================== BASIC SERIAL I/O ==================== func (f *MTBoss) sendRaw(data []byte) error { _, err := f.port.Write(data) return err } func (f *MTBoss) readExact(length int) ([]byte, error) { buf := make([]byte, length) read := 0 for read < length { n, err := f.port.Read(buf[read:]) if err != nil { return nil, err } if n == 0 { time.Sleep(2 * time.Millisecond) } read += n } return buf, nil } // ==================== BROM REGISTER OPERATIONS ==================== func (f *MTBoss) readReg16(addr uint32) (uint16, error) { cmd := make([]byte, 9) cmd[0] = 0xA2 binary.BigEndian.PutUint32(cmd[1:5], addr) binary.BigEndian.PutUint32(cmd[5:9], 1) if err := f.sendRaw(cmd); err != nil { return 0, err } if _, err := f.readExact(9); err != nil { // Echo return 0, err } resp, err := f.readExact(2) if err != nil { return 0, err } return binary.BigEndian.Uint16(resp), nil } func (f *MTBoss) writeReg16(addr uint32, val uint16) error { cmd := make([]byte, 9) cmd[0] = 0xD2 binary.BigEndian.PutUint32(cmd[1:5], addr) binary.BigEndian.PutUint32(cmd[5:9], 1) if err := f.sendRaw(cmd); err != nil { return err } if _, err := f.readExact(9); err != nil { return err } if ack, err := f.readExact(2); err != nil || !bytes.Equal(ack, []byte{0x00, 0x01}) { return fmt.Errorf("writeReg16 cmd ACK error: %v", ack) } valBuf := make([]byte, 2) binary.BigEndian.PutUint16(valBuf, val) if err := f.sendRaw(valBuf); err != nil { return err } if _, err := f.readExact(2); err != nil { return err } if ack, err := f.readExact(2); err != nil || !bytes.Equal(ack, []byte{0x00, 0x01}) { return fmt.Errorf("writeReg16 data ACK error: %v", ack) } return nil } func (f *MTBoss) readReg32(addr uint32) (uint32, error) { cmd := make([]byte, 9) cmd[0] = 0xD1 binary.BigEndian.PutUint32(cmd[1:5], addr) binary.BigEndian.PutUint32(cmd[5:9], 1) if err := f.sendRaw(cmd); err != nil { return 0, err } if _, err := f.readExact(9); err != nil { return 0, err } resp, err := f.readExact(8) // status[2] + data[4] + status[2] if err != nil { return 0, err } return binary.LittleEndian.Uint32(resp[2:6]), nil } func (f *MTBoss) writeReg32(addr uint32, val uint32) error { cmd := make([]byte, 9) cmd[0] = 0xD4 binary.BigEndian.PutUint32(cmd[1:5], addr) binary.BigEndian.PutUint32(cmd[5:9], 1) if err := f.sendRaw(cmd); err != nil { return err } if _, err := f.readExact(9); err != nil { return err } if ack, err := f.readExact(2); err != nil || !bytes.Equal(ack, []byte{0x00, 0x01}) { return fmt.Errorf("writeReg32 cmd ACK error: %v", ack) } valBuf := make([]byte, 4) binary.BigEndian.PutUint32(valBuf, val) if err := f.sendRaw(valBuf); err != nil { return err } if _, err := f.readExact(4); err != nil { return err } if ack, err := f.readExact(2); err != nil || !bytes.Equal(ack, []byte{0x00, 0x01}) { return fmt.Errorf("writeReg32 data ACK error: %v", ack) } return nil } // ==================== BOOTROM HANDSHAKE ==================== func (f *MTBoss) WaitAndConnect(timeoutSec int) error { fmt.Println("\n============================================================") fmt.Println("Waiting for MTBoss (MT6261) BootROM Connection") fmt.Println("============================================================") fmt.Println("1. Power OFF phone completely") fmt.Println("2. Press and hold BOOT key (or Power button)") fmt.Println("3. Plug in USB cable now...") start := time.Now() dots := 0 for time.Since(start) < time.Duration(timeoutSec)*time.Second { _ = f.sendRaw([]byte{0xA0}) time.Sleep(5 * time.Millisecond) b := make([]byte, 1) n, _ := f.port.Read(b) if n > 0 && b[0] == 0x5F { // Second sync packet _ = f.sendRaw([]byte{0x0A, 0x50, 0x05}) ack3, err := f.readExact(3) if err == nil && bytes.Equal(ack3, []byte{0xF5, 0xAF, 0xFA}) { fmt.Println("\nConnected to MT6261 BootROM!") chip, err := f.readReg16(0x80000008) if err == nil { f.chipID = chip fmt.Printf("Chip ID: 0x%04X\n", chip) } // Disable watchdogs & enable USB download _ = f.writeReg16(0xA0030000, 0x2200) // System watchdog _ = f.writeReg16(0xA0700A28, 0x8000) // USB download mode _ = f.writeReg16(0xA0700A24, 0x0002) // Battery watchdog _ = f.writeReg32(BOOT_ENG_BASE, 2) // Boot engine memory map mode 2 fmt.Println("BootROM initialized & watchdogs disabled.") return nil } } dots++ if dots%20 == 0 { fmt.Print(".") } } return fmt.Errorf("timeout waiting for BootROM sync") } // ==================== SFI HARDWARE MAC MODE ==================== func (f *MTBoss) sfiMacCmdWrite(cmdByte byte, addr *uint32, data []byte) error { var payload []byte payload = append(payload, cmdByte) if addr != nil { addrBytes := make([]byte, 4) binary.BigEndian.PutUint32(addrBytes, *addr) payload = append(payload, addrBytes[1:]...) // 3-byte big-endian address } payload = append(payload, data...) totalLen := uint32(len(payload)) // 1. Write payload to GPRAM (0xA0140800) in 32-bit LE words for i := uint32(0); i < totalLen; i += 4 { end := i + 4 if end > totalLen { end = totalLen } chunk := make([]byte, 4) copy(chunk, payload[i:end]) valLE := binary.LittleEndian.Uint32(chunk) if err := f.writeReg32(SFI_GPRAM+i, valLE); err != nil { return err } } // 2. Mask AHB Channel 2 misc3, _ := f.readReg32(SFI_MISC_CTL3) _ = f.writeReg32(SFI_MISC_CTL3, misc3|(1<<9)) // 3. Enable MAC Mode FIRST (SFI_MAC_SEL bit 28 | SFI_MAC_EN bit 3) macVal := uint32(SFI_MAC_SEL | SFI_MAC_EN) if err := f.writeReg32(SFI_MAC_CTL, macVal); err != nil { return err } // 4. Set OUTL and INL lengths while MAC mode is active _ = f.writeReg32(SFI_MAC_OUTL, totalLen) _ = f.writeReg32(SFI_MAC_INL, 0) // 5. Trigger transaction (SFI_TRIG bit 2) _ = f.writeReg32(SFI_MAC_CTL, macVal|SFI_TRIG) // 6. Poll for completion (WIP_READY bit 1 set, WIP bit 0 clear) for i := 0; i < 300; i++ { v, err := f.readReg32(SFI_MAC_CTL) if err == nil && (v&SFI_WIP_READY != 0) && (v&SFI_WIP == 0) { break } time.Sleep(1 * time.Millisecond) } // 7. Clean up MAC mode and unmask AHB _ = f.writeReg32(SFI_MAC_CTL, 0) _ = f.writeReg32(SFI_MISC_CTL3, misc3&^(1<<9)) return nil } func (f *MTBoss) sfiMacCmdRead(cmdByte byte, readLen uint32) ([]byte, error) { // 1. Write command to GPRAM if err := f.writeReg32(SFI_GPRAM, uint32(cmdByte)); err != nil { return nil, err } // 2. Mask AHB Channel 2 misc3, _ := f.readReg32(SFI_MISC_CTL3) _ = f.writeReg32(SFI_MISC_CTL3, misc3|(1<<9)) // 3. Enable MAC Mode FIRST macVal := uint32(SFI_MAC_SEL | SFI_MAC_EN) _ = f.writeReg32(SFI_MAC_CTL, macVal) // 4. Set OUTL and INL lengths _ = f.writeReg32(SFI_MAC_OUTL, 1) _ = f.writeReg32(SFI_MAC_INL, readLen) // 5. Trigger _ = f.writeReg32(SFI_MAC_CTL, macVal|SFI_TRIG) // 6. Poll completion for i := 0; i < 300; i++ { v, err := f.readReg32(SFI_MAC_CTL) if err == nil && (v&SFI_WIP_READY != 0) && (v&SFI_WIP == 0) { break } time.Sleep(1 * time.Millisecond) } // 7. Read response from GPRAM totalBytes := 1 + readLen var resBuf bytes.Buffer for i := uint32(0); i < (totalBytes + 3); i += 4 { val, _ := f.readReg32(SFI_GPRAM + i) wordBytes := make([]byte, 4) binary.LittleEndian.PutUint32(wordBytes, val) resBuf.Write(wordBytes) } // 8. Clean up _ = f.writeReg32(SFI_MAC_CTL, 0) _ = f.writeReg32(SFI_MISC_CTL3, misc3&^(1<<9)) fullData := resBuf.Bytes() if uint32(len(fullData)) < 1+readLen { return nil, fmt.Errorf("short SFI MAC read") } return fullData[1 : 1+readLen], nil } // ==================== SPI FLASH HIGH-LEVEL ==================== func (f *MTBoss) ReadJEDECID() ([]byte, error) { return f.sfiMacCmdRead(0x9F, 3) } func (f *MTBoss) ReadStatusRegister() (byte, error) { data, err := f.sfiMacCmdRead(0x05, 1) if err != nil || len(data) == 0 { return 0, err } return data[0], nil } func (f *MTBoss) WaitUntilReady(timeoutSec int) error { start := time.Now() for time.Since(start) < time.Duration(timeoutSec)*time.Second { sr, err := f.ReadStatusRegister() if err == nil && (sr&SR_WIP == 0) { return nil } time.Sleep(5 * time.Millisecond) } return fmt.Errorf("timeout waiting for SPI flash ready") } func (f *MTBoss) UnlockWriteProtection() error { sr, err := f.ReadStatusRegister() if err == nil { fmt.Printf("SPI Flash Status Register: 0x%02X\n", sr) if sr&(SR_BP0|SR_BP1|SR_BP2|SR_BP3) != 0 { fmt.Println("Write protection enabled - disabling...") _ = f.sfiMacCmdWrite(0x50, nil, nil) // Volatile WREN _ = f.sfiMacCmdWrite(0x01, nil, []byte{0x00}) _ = f.WaitUntilReady(5) sr, _ = f.ReadStatusRegister() fmt.Printf("Status Register after unlocking: 0x%02X\n", sr) } } return nil } func (f *MTBoss) EnableWrite() error { return f.sfiMacCmdWrite(0x06, nil, nil) } func (f *MTBoss) EraseSector(addr uint32) error { if err := f.WaitUntilReady(5); err != nil { return err } if err := f.EnableWrite(); err != nil { return err } if err := f.sfiMacCmdWrite(0x20, &addr, nil); err != nil { return err } return f.WaitUntilReady(5) } func (f *MTBoss) PageProgram(addr uint32, data []byte) error { const maxChunk = 64 offset := 0 for offset < len(data) { end := offset + maxChunk if end > len(data) { end = len(data) } chunk := data[offset:end] currAddr := addr + uint32(offset) if err := f.WaitUntilReady(5); err != nil { return err } if err := f.EnableWrite(); err != nil { return err } if err := f.sfiMacCmdWrite(0x02, &currAddr, chunk); err != nil { return err } if err := f.WaitUntilReady(5); err != nil { return err } offset += len(chunk) } return nil } // ==================== BROM MEMORY-MAPPED READING ==================== func (f *MTBoss) ReadFlash(address uint32, length uint32) ([]byte, error) { var result bytes.Buffer remaining := length currAddr := address const blkSize = 1024 for remaining > 0 { rsize := remaining if rsize > blkSize { rsize = blkSize } wordsCnt := rsize >> 2 cmd := make([]byte, 9) cmd[0] = 0xD1 binary.BigEndian.PutUint32(cmd[1:5], currAddr) binary.BigEndian.PutUint32(cmd[5:9], wordsCnt) if err := f.sendRaw(cmd); err != nil { return nil, err } if _, err := f.readExact(9); err != nil { return nil, err } respLen := (int(wordsCnt) * 4) + 4 resp, err := f.readExact(respLen) if err != nil { return nil, err } // Skip 2-byte header and 2-byte status footer rawWords := resp[2 : 2+int(wordsCnt)*4] for i := 0; i < len(rawWords); i += 4 { wordVal := binary.LittleEndian.Uint32(rawWords[i : i+4]) wordBE := make([]byte, 4) binary.BigEndian.PutUint32(wordBE, wordVal) result.Write(wordBE) } currAddr += rsize remaining -= rsize progress := float64(length-remaining) / float64(length) * 100.0 fmt.Printf("\rReading: %.1f%%", progress) } fmt.Println("\nRead complete.") return result.Bytes(), nil } // ==================== HIGH-LEVEL FLASH OPERATIONS ==================== func (f *MTBoss) WriteRegion(address uint32, data []byte, verify bool) error { fmt.Printf("\n============================================================\n") fmt.Printf("Flashing Region at 0x%08X (Size: %d bytes / 0x%X)\n", address, len(data), len(data)) fmt.Printf("============================================================\n") _ = f.UnlockWriteProtection() startSector := address & ^uint32(FLASH_SECTOR_SZ-1) endAddr := address + uint32(len(data)) fmt.Printf("Erasing sectors from 0x%08X to 0x%08X...\n", startSector, endAddr) for sec := startSector; sec < endAddr; sec += FLASH_SECTOR_SZ { fmt.Printf(" Erasing sector at 0x%08X...\n", sec) if err := f.EraseSector(sec); err != nil { return fmt.Errorf("failed erasing sector 0x%08X: %v", sec, err) } } fmt.Println("Sectors erased.") fmt.Printf("Programming %d bytes to 0x%08X...\n", len(data), address) offset := 0 for offset < len(data) { end := offset + 256 if end > len(data) { end = len(data) } chunk := data[offset:end] currAddr := address + uint32(offset) if err := f.PageProgram(currAddr, chunk); err != nil { return fmt.Errorf("failed programming at 0x%08X: %v", currAddr, err) } offset += len(chunk) fmt.Printf("\rProgramming: %.1f%%", float64(offset)/float64(len(data))*100.0) } fmt.Println("\nProgramming complete.") if verify { fmt.Printf("Verifying %d bytes at 0x%08X...\n", len(data), address) readData, err := f.ReadFlash(address, uint32(len(data))) if err != nil { return fmt.Errorf("verification read failed: %v", err) } refMD5 := md5.Sum(data) readMD5 := md5.Sum(readData) fmt.Printf("Reference MD5: %s\n", hex.EncodeToString(refMD5[:])) fmt.Printf("Readback MD5: %s\n", hex.EncodeToString(readMD5[:])) if bytes.Equal(data, readData) { fmt.Println("\n*** VERIFICATION PASSED - EXACT BYTE-FOR-BYTE MATCH ***") } else { return fmt.Errorf("verification FAILED - binary mismatch!") } } return nil } func (f *MTBoss) Reset() { fmt.Println("Resetting device...") _ = f.writeReg16(0xA003001C, 0x1209) } // ==================== MAIN CLI ==================== func main() { portFlag := flag.String("port", "auto", "Serial port device (e.g. /dev/ttyUSB0, /dev/ttyUSB1 or auto)") modeFlag := flag.String("mode", "flash", "Mode of operation: flash, read, erase, identify") fileFlag := flag.String("file", "", "Input/Output binary file path") startFlag := flag.String("start", "", "Flash start offset address (e.g. 0, 0x0000, 4K)") offsetFlag := flag.String("offset", "0x00000000", "Flash offset address (alias for -start, default 0)") sizeFlag := flag.String("size", "", "Operation size in bytes/hex/units (e.g. 4MB, 64KB, 0x400000)") lengthFlag := flag.String("length", "0x400000", "Operation size (alias for -size, default 4MiB / 0x400000)") verifyFlag := flag.Bool("verify", true, "Verify flash write via readback") timeoutFlag := flag.Int("timeout", 600, "Timeout in seconds waiting for BootROM sync") flag.Parse() // Determine start address string (prefer -start if explicitly set) startStr := *offsetFlag if *startFlag != "" { startStr = *startFlag } // Determine size string (prefer -size if explicitly set) sizeStr := *lengthFlag if *sizeFlag != "" { sizeStr = *sizeFlag } start, err := parseSizeOrOffset(startStr) if err != nil { fmt.Printf("Invalid start/offset format '%s': %v\n", startStr, err) os.Exit(1) } size, err := parseSizeOrOffset(sizeStr) if err != nil { fmt.Printf("Invalid size/length format '%s': %v\n", sizeStr, err) os.Exit(1) } flasher, err := NewMTBoss(*portFlag) if err != nil { fmt.Printf("Error opening serial port: %v\n", err) os.Exit(1) } defer flasher.Close() if err := flasher.WaitAndConnect(*timeoutFlag); err != nil { fmt.Printf("BootROM Connection failed: %v\n", err) os.Exit(1) } switch *modeFlag { case "identify": id, err := flasher.ReadJEDECID() if err == nil && len(id) >= 3 { fmt.Printf("JEDEC ID: %02X %02X %02X\n", id[0], id[1], id[2]) } else { fmt.Printf("Could not read JEDEC ID: %v\n", err) } flasher.Reset() case "read": if *fileFlag == "" { fmt.Println("Error: --file is required for read mode") os.Exit(1) } fmt.Printf("Reading %d (0x%X) bytes from 0x%08X to %s...\n", size, size, uint32(start), *fileFlag) data, err := flasher.ReadFlash(uint32(start), uint32(size)) if err != nil { fmt.Printf("Read failed: %v\n", err) os.Exit(1) } if err := os.WriteFile(*fileFlag, data, 0644); err != nil { fmt.Printf("Failed writing file: %v\n", err) os.Exit(1) } hash := md5.Sum(data) fmt.Printf("Successfully saved %s (MD5: %s)\n", *fileFlag, hex.EncodeToString(hash[:])) flasher.Reset() case "erase": fmt.Printf("Erasing %d (0x%X) bytes at 0x%08X...\n", size, size, uint32(start)) startSec := uint32(start) & ^uint32(FLASH_SECTOR_SZ-1) endSec := uint32(start + size) for sec := startSec; sec < endSec; sec += FLASH_SECTOR_SZ { fmt.Printf("Erasing sector at 0x%08X...\n", sec) if err := flasher.EraseSector(sec); err != nil { fmt.Printf("Erase failed: %v\n", err) os.Exit(1) } } fmt.Println("Erase complete.") flasher.Reset() case "flash": if *fileFlag == "" { fmt.Println("Error: --file is required for flash mode") os.Exit(1) } data, err := os.ReadFile(*fileFlag) if err != nil { fmt.Printf("Failed reading file %s: %v\n", *fileFlag, err) os.Exit(1) } // If size was explicitly set or if size < len(data), limit payload to specified size if uint64(len(data)) > size { fmt.Printf("Limiting file payload from %d to specified size %d (0x%X) bytes\n", len(data), size, size) data = data[:size] } fHash := md5.Sum(data) fmt.Printf("Loaded %s (%d bytes, MD5: %s)\n", *fileFlag, len(data), hex.EncodeToString(fHash[:])) if err := flasher.WriteRegion(uint32(start), data, *verifyFlag); err != nil { fmt.Printf("Flashing failed: %v\n", err) os.Exit(1) } fmt.Println("\n============================================================") fmt.Println("Operation completed successfully!") fmt.Println("============================================================") flasher.Reset() default: fmt.Printf("Unknown mode: %s\n", *modeFlag) os.Exit(1) } }