Как изменить сценарии компоновщика с samd21j18a на samd21e16b для sam-ba?

#memory #tcl #bootloader #linker-scripts #samd21

Вопрос:

Я пытаюсь изменить сценарии компоновщика, которые использует sam-ba (помощник загрузчика sam). Сценарии компоновки написаны для samd21j18a корпорацией Atmel (tcl_lib и applet). Объем оперативной памяти samd21e16b составляет 8 КБ, а объем флэш-памяти — 64 кБ, исходя из таблицы данных. Основываясь на документации, мне нужно изменить

  1. appletAddr и appletMailboxAddr соответственно в tcl_lib, в зависимости от выбранного устройства и SRAM, занятого загрузчиком SAM-BA.
  2. Настройка скрипта компоновщика апплетов ASF SAM-BA для SAMD21E16B и последней версии ASF. Мне нужно обновить разделы, которые основаны на выбранном устройстве и размере SRAM, занимаемом загрузчиком SAM-BA.

Есть ли у вас какие-либо ресурсы, которые помогут понять эту информацию в сценариях компоновщика для настройки чипа (samd21e16b)?

Что такое appletAddr и appletMailboxAddr?

Как они записывают размер sram:

 sram (W!RX) : ORIGIN = 0x20002000, LENGTH = 0x00002000 /* sram, 4K - sizeof(romcodesram) */
 

tcl_lib:

 set cidr_addr 0x41002018
# *****************************************************************************
#                       CHIP NAME   CHIPID_CIDR
# *****************************************************************************
array set devicesList { samd21j18a 0x10010000
                        samd21j17a 0x10010001
                        samd21j16a 0x10010002
                        samd21j15a 0x10010003
                        samd21g18a 0x10010005
                        samd21g17a 0x10010006
                        samd21g16a 0x10010007
                        samd21g15a 0x10010008
                        samd21e18a 0x1001000A
                        samd21e17a 0x1001000B
                        samd21e16a 0x1001000C
                        samd21e15a 0x1001000D
                      }
global target
global commandLineMode
set isValidChipOfBoard 0
set version_mask 0xFFBF00FF
set chipname_list [array names ::devicesList]
set chip_id [format "0xx" [TCL_Read_Int $target(handle) $cidr_addr err_code]]
puts "Read device Chip ID at $cidr_addr --- get $chip_id"
set proc_id_masked [format "0xx" [expr $chip_id amp; $version_mask]]
foreach {key value} [array get devicesList] {
   set masked_chipId_Cidr [format "0xx" [expr $value amp; $version_mask]]
   if {[regexp $proc_id_masked $masked_chipId_Cidr] != 0} {
       puts "-I- Found chip : $key (Chip ID : $chip_id)"
       set isValidChipOfBoard 1
       break
   }
} 

if { $isValidChipOfBoard == 0 } {
    if { $commandLineMode == 1 } {
        puts "-E- Invalid device or board!"
    } else {
        tk_messageBox -title "Invalid chip ID" -message "Can't connect $target(board)n" -icon error -type ok
    }
    TCL_Close $target(handle)
    exit
}

namespace eval BOARD {
    variable sramSize         0x00008000
    variable maxBootSize      0
    # Vdd Memory 1.8V = 0 / Vdd Memory 3.3V = 1
    variable extRamVdd 1
    # External SDRAM = 0 / External DDR = 1 External PSRAM = 2 (not used)
    variable extRamType 0
    # Set bus width (16 or 32)
    variable extRamDataBusWidth 16
    # DDRAM Model (not used)
    variable extDDRamModel 0
}

# Standard applet commands   some SAMD21 specific commands
array set appletCmdSamd21 {
    init            0x00
    fullErase       0x01
    write           0x02
    read            0x03
    lock            0x04
    unlock          0x05
    gpnvm           0x06
    security        0x07
    erasebuffer     0x08
    binarypage      0x09
    otpRead         0x0a
    otpWrite        0x0b
    listbadblocks   0x10
    tagBlock        0x11
    readUniqueID    0x12
    eraseBlocks     0x13
    batchErase      0x14
    pmeccParam      0x15
    pmeccBoot       0x16
    switchEccMode   0x17
    trimffsMode     0x18
    eraseRow        0x40
    readDeviceID    0x41
    readLocks       0x42
    readFuses       0x43
    eraseApp        0x44
}

set target(board) "samd21_xplained_pro"

################################################################################
## PROCEDURES FOR COMPATIBILITY WITH OLDER SAM-BA VERSIONS AND USER DEFINED
################################################################################
if { [ catch { source "$libPath(extLib)/common/functions.tcl"} errMsg] } {
    if {$commandLineMode == 0} {
        tk_messageBox -title "File not found" -message "Function file not found:n$errMsg" -type ok -icon error
    } else {
        puts "-E- Function file not found:n$errMsg"
        puts "-E- Connection abort"
    }
    exit
}

array set memoryAlgo {
    "SRAM"            "::atsamd21_sram"
    "Flash"           "::atsamd21_flash"
    "Peripheral"      "::atsamd21_peripheral"
}

################################################################################
## Low Level Initialization
################################################################################


################################################################################
## SRAM : 32k
################################################################################
array set atsamd21_sram {
    dftDisplay  0
    dftDefault  0
    dftAddress  0x20000000
    dftSize     0x8000
    dftSend     "RAM::sendFile"
    dftReceive  "RAM::receiveFile"
    dftScripts  ""
}

################################################################################
## FLASH : 256k
################################################################################
array set atsamd21_flash {
    dftDisplay  1
    dftDefault  1
    dftAddress  0x00000
    dftSize     0x40000
    dftSend     "FLASH::SendFileNoLock"
    dftReceive  "FLASH::ReceiveFile"
    dftScripts  "::atsamd21_flash_scripts"
}

array set atsamd21_flash_scripts {
        "Read Device ID"                        "FLASH::ReadDeviceID"
        "Read Lock Fuses"                       "FLASH::ReadLocks"
        "Unlock All"                            "FLASH::UnlockAll"
        "Set Lock Bit 00"                       "FLASH::SetLock 0"
        "Set Lock Bit 01"                       "FLASH::SetLock 1"
        "Set Lock Bit 02"                       "FLASH::SetLock 2"
        "Set Lock Bit 03"                       "FLASH::SetLock 3"
        "Set Lock Bit 04"                       "FLASH::SetLock 4"
        "Set Lock Bit 05"                       "FLASH::SetLock 5"
        "Set Lock Bit 06"                       "FLASH::SetLock 6"
        "Set Lock Bit 07"                       "FLASH::SetLock 7"
        "Set Lock Bit 08"                       "FLASH::SetLock 8"
        "Set Lock Bit 09"                       "FLASH::SetLock 9"
        "Set Lock Bit 10"                       "FLASH::SetLock 10"
        "Set Lock Bit 11"                       "FLASH::SetLock 11"
        "Set Lock Bit 12"                       "FLASH::SetLock 12"
        "Set Lock Bit 13"                       "FLASH::SetLock 13"
        "Set Lock Bit 14"                       "FLASH::SetLock 14"
        "Set Lock Bit 15"                       "FLASH::SetLock 15"
        "Invalidate application"                "FLASH::EraseRow 32"
        "Erase application area"                "FLASH::EraseApp"
        "Read Fuses"                            "FLASH::ReadFuses"
        "Set Security Bit"                      "FLASH::SetSecurity"
}

set FLASH::appletAddr             0x20002000
set FLASH::appletMailboxAddr      0x20002040
set FLASH::appletFileName         "$libPath(extLib)/$target(board)/applet-flash-samd21j18a.bin"

# Initialize FLASH
if {[catch {FLASH::Init} dummy_err]} { 
    if {$commandLineMode == 0} {
        tk_messageBox -title "FLASH init" -message "Failed to initialize FLASH access" -icon error -type ok
    } else {
        puts "-E- Error during FLASH initialization"
        puts "-E- Connection abort"
    }
    # Close link
    TCL_Close $target(handle)
    exit
    } else {
        #retrieve additionnal parameters from the Init function
        set appletAddrArgvps      [expr $FLASH::appletMailboxAddr   0x18]
        set appletAddrArgvnp      [expr $FLASH::appletMailboxAddr   0x1c]
        set appletAddrArgvasp     [expr $FLASH::appletMailboxAddr   0x20]

        set flashPageSize         [TCL_Read_Int $target(handle) $appletAddrArgvps]
        set flashNbPage         [TCL_Read_Int $target(handle) $appletAddrArgvnp]
        set flashAppStartPage     [TCL_Read_Int $target(handle) $appletAddrArgvasp]

        puts "flashPageSize     [format "0xx" $flashPageSize]"
        puts "flashNbPage         [format "%d" $flashNbPage]"
        puts "flashAppStartPage [format "%d" $flashAppStartPage]"
        puts "-I- FLASH initialized"
}


################################################################################
array set atsamd21_peripheral {
    dftDisplay  0
    dftDefault  0
    dftAddress  0x40000000
    dftSize     0x10000000
    dftSend     ""
    dftReceive  ""
    dftScripts  ""
}

#===============================================================================
#  proc FLASH::ReadDeviceID
#===============================================================================
proc FLASH::ReadDeviceID { } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd       [expr $appletMailboxAddr]
    set appletAddrStatus    [expr $appletMailboxAddr   0x04]
    set appletAddrArgv0     [expr $appletMailboxAddr   0x08]
    set appletAddrArgv1     [expr $appletMailboxAddr   0x0c]
    set appletAddrArgv2     [expr $appletMailboxAddr   0x10]
    set appletAddrArgv3     [expr $appletMailboxAddr   0x14]

    # Init the ping pong algorithm: the buffer is active
    set bufferAddress $GENERIC::appletBufferAddress

    # Write the Cmd op code in the argument area
    if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(readDeviceID) $appletAddrCmd} dummy_err] } {
        error "Error Writing Applet command ($dummy_err)"
    }
    
    # Write the buffer address in the argument area
    if {[catch {TCL_Write_Int $target(handle) $bufferAddress $appletAddrArgv0} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    # Launch the applet Jumping to the appletAddr
    if {[catch {set result [GENERIC::Run $::appletCmdSamd21(readDeviceID)]} dummy_err]} {
        error "Applet readDeviceID command has not been launched ($dummy_err)"
    }

    puts "buffer address [format "0xx" $bufferAddress]"

    puts "Device ID :"

    set addr [expr $bufferAddress]
    # Return the error code returned by the applet
    if {[catch {set data [TCL_Read_Int $target(handle) $addr]} dummy_err] } {
        error "Error reading the buffer containing Device ID"
    }

    puts [format "0xx" $data]
}

#===============================================================================
#  proc FLASH::ReadFuses
#===============================================================================
proc FLASH::ReadFuses { } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd       [expr $appletMailboxAddr]
    set appletAddrStatus    [expr $appletMailboxAddr   0x04]
    set appletAddrArgv0     [expr $appletMailboxAddr   0x08]
    set appletAddrArgv1     [expr $appletMailboxAddr   0x0c]

    # Init the ping pong algorithm: the buffer is active
    set bufferAddress $GENERIC::appletBufferAddress

    # Write the Cmd op code in the argument area
    if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(readFuses) $appletAddrCmd} dummy_err] } {
        error "Error Writing Applet command ($dummy_err)"
    }
    
    # Write the buffer address in the argument area
    if {[catch {TCL_Write_Int $target(handle) $bufferAddress $appletAddrArgv0} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    # Launch the applet Jumping to the appletAddr
    if {[catch {set result [GENERIC::Run $::appletCmdSamd21(readFuses)]} dummy_err]} {
        error "Applet readDeviceID command has not been launched ($dummy_err)"
    }

    puts "buffer address [format "0xx" $bufferAddress]"

    puts "Fuses :"

    set i 0
    set addr [expr $bufferAddress]
    while {$i < [expr 2]} {
        # Return the error code returned by the applet
        if {[catch {set data [TCL_Read_Int $target(handle) $addr]} dummy_err] } {
            error "Error reading the buffer containing Device ID"
        }
        incr addr  4
        incr i  1
        puts [format "0xx" $data]
    }
}

#===============================================================================
#  proc FLASH::ReadLocks
#===============================================================================
proc FLASH::ReadLocks { } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd       [expr $appletMailboxAddr]
    set appletAddrStatus    [expr $appletMailboxAddr   0x04]
    set appletAddrArgv0     [expr $appletMailboxAddr   0x08]
    set appletAddrArgv1     [expr $appletMailboxAddr   0x0c]
    set appletAddrArgv2     [expr $appletMailboxAddr   0x10]
    set appletAddrArgv3     [expr $appletMailboxAddr   0x14]

    # Init the ping pong algorithm: the buffer is active
    set bufferAddress $GENERIC::appletBufferAddress

    # Write the Cmd op code in the argument area
    if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(readLocks) $appletAddrCmd} dummy_err] } {
        error "Error Writing Applet command ($dummy_err)"
    }
    
    # Write the buffer address in the argument area
    if {[catch {TCL_Write_Int $target(handle) $bufferAddress $appletAddrArgv0} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    # Launch the applet Jumping to the appletAddr
    if {[catch {set result [GENERIC::Run $::appletCmdSamd21(readLocks)]} dummy_err]} {
        error "Applet readDeviceID command has not been launched ($dummy_err)"
    }

    puts "buffer address [format "0xx" $bufferAddress]"

    puts "Lock status :"

    set addr [expr $bufferAddress]
    # Return the error code returned by the applet
    if {[catch {set data [TCL_Read_Short $target(handle) $addr]} dummy_err] } {
        error "Error reading the buffer containing Device ID"
    }

    puts [format "0x%4x" $data]
}

#===============================================================================
#  proc FLASH::SetLock
#===============================================================================
proc FLASH::SetLock { lockbit } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd       [expr $appletMailboxAddr]
    set appletAddrStatus    [expr $appletMailboxAddr   0x04]
    set appletAddrArg_value [expr $appletMailboxAddr   0x08]

    if {$lockbit > [expr 16]} {
        error "Wrong lock bit number"
    }

    set writemask [expr 1 << $lockbit ]

    # Write the Cmd op code in the argument area
    if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(lock) $appletAddrCmd} dummy_err] } {
        error "Error Writing Applet command ($dummy_err)"
    }
    # Write value in the argument area
    if {[catch {TCL_Write_Int $target(handle) [expr $lockbit] $appletAddrArg_value} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    # Launch the applet Jumping to the appletAddr
    if {[catch {set result [GENERIC::Run $::appletCmdSamd21(lock)]} dummy_err]} {
        error "Applet lock command has not been launched ($dummy_err)"
    }

    puts "Region locked"
}


#===============================================================================
#  proc FLASH::UnlockAll
#===============================================================================
proc FLASH::UnlockAll { } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd       [expr $appletMailboxAddr]
    set appletAddrStatus    [expr $appletMailboxAddr   0x04]
    set appletAddrArg_value [expr $appletMailboxAddr   0x08]

    set lockbit 0
    while { $lockbit < [expr 16]} {
        set writemask [expr 1 << $lockbit ]

        # Write the Cmd op code in the argument area
        if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(unlock) $appletAddrCmd} dummy_err] } {
            error "Error Writing Applet command ($dummy_err)"
        }
        # Write value in the argument area
        if {[catch {TCL_Write_Int $target(handle) [expr $lockbit] $appletAddrArg_value} dummy_err] } {
            error "[format "0xx" $dummy_err]"
        }
        # Launch the applet Jumping to the appletAddr
        if {[catch {set result [GENERIC::Run $::appletCmdSamd21(unlock)]} dummy_err]} {
            error "Applet lock command has not been launched ($dummy_err)"
        }

        puts "Region ($lockbit) unlocked"

        incr lockbit  1
    }
}

#===============================================================================
#  proc FLASH::SetSecurity
#===============================================================================
proc FLASH::SetSecurity { } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd       [expr $appletMailboxAddr]
    set appletAddrStatus    [expr $appletMailboxAddr   0x04]
    set appletAddrArg_param [expr $appletMailboxAddr   0x08]

    # Write the Cmd op code in the argument area
    if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(security) $appletAddrCmd} dummy_err] } {
        error "Error Writing Applet command ($dummy_err)"
    }
    # Write the param value in the argument area
    if {[catch {TCL_Write_Int $target(handle) 1 $appletAddrArg_param} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    puts "About to launch set security bit procedure ..."

    # Launch the applet Jumping to the appletAddr
    if {[catch {set result [GENERIC::Run $::appletCmdSamd21(security)]} dummy_err]} {
        error "Applet security command has not been launched ($dummy_err)"
    } else {
        puts "Part is secured"
    }
}

#===============================================================================
#  proc FLASH::SendFileNoLock
#===============================================================================
proc FLASH::SendFileNoLock { name addr } {
    variable flashSize  
    variable flashLockRegionSize   
    variable flashNumbersLockBits 
    variable appletBufferAddress
    global   commandLineMode

    if { [catch {set f [open $name r]}] } {
        puts "-E- Can't open file $name"
        return -1
    }
    fconfigure $f -translation binary

    #First Step check the locked sector 
    set dummy_err 0
    set rewrite 0
    set size [file size $name]

    set dest [expr $addr amp; [expr  $flashSize - 1]]
    set first_page [expr $dest / $::flashPageSize]

    puts "File size : $size"
    puts "Flash size : $flashSize Flash page size : $::flashPageSize First page : $first_page"
    puts "Dest : $dest"

    if { $first_page < $::flashAppStartPage } {
        if {$commandLineMode == 0} {
            set answer [tk_messageBox -title "Attempt to write monitor area"
            -message " Writing to the monitor area is forbidden, write operation aborted "
            -icon error 
            -type ok]
        }
        return -1
    }

    if {[catch {GENERIC::Write $dest $size $f 0} dummy_err] } {
        puts "-E- Generic::Write returned error ($dummy_err)"
        close $f
        return -1
    }
    close $f
}

#===============================================================================
#  proc FLASH::EraseRow
#===============================================================================
proc FLASH::EraseRow { flashrow } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd               [expr $appletMailboxAddr]
    set appletAddrStatus            [expr $appletMailboxAddr   0x04]
    set appletAddrArg_param         [expr $appletMailboxAddr   0x08]

    if {$flashrow > [expr 1024]} {
        error "Wrong flash region number"
    }

    if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(eraseRow) $appletAddrCmd} dummy_err] } {
        error "Error Writing Applet command ($dummy_err)"
    }
    # Write the param value in the argument area
    if {[catch {TCL_Write_Int $target(handle) [expr $flashrow] $appletAddrArg_param} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    # Launch the applet Jumping to the appletAddr
    if {[catch {set result [GENERIC::Run $::appletCmdSamd21(eraseRow)]} dummy_err]} {
        error "Applet eraseRow command has not been launched ($dummy_err)"
    }
    puts "Flash memory row erased."

}

#===============================================================================
#  proc FLASH::EraseApp
#===============================================================================
proc FLASH::EraseApp { } {
    global   target
    variable appletMailboxAddr
    set      dummy_err 0

    # Mailbox is 32 word long (add variable here if you need read/write more data)
    set appletAddrCmd               [expr $appletMailboxAddr]
    set appletAddrStatus            [expr $appletMailboxAddr   0x04]
    set appletAddrArg_start_row     [expr $appletMailboxAddr   0x08]
    set appletAddrArg_end_row       [expr $appletMailboxAddr   0x0c]

    # Write the Cmd op code in the argument area
    if {[catch {TCL_Write_Int $target(handle) $::appletCmdSamd21(eraseApp) $appletAddrCmd} dummy_err] } {
        error "Error Writing Applet command ($dummy_err)"
    }
    
    set start    [expr $::flashAppStartPage/4]
    set end      [expr $::flashNbPage/4]

    # Write the starting row number in the argument area
    if {[catch {TCL_Write_Int $target(handle) [expr $start] $appletAddrArg_start_row} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    # Write the ending row number in the argument area
    if {[catch {TCL_Write_Int $target(handle) [expr $end] $appletAddrArg_end_row} dummy_err] } {
        error "[format "0xx" $dummy_err]"
    }

    puts "Start row: [format "0xx" $start]"
    puts "End row: [format "0xx" $end]"

    # Launch the applet Jumping to the appletAddr
    if {[catch {set result [GENERIC::Run $::appletCmdSamd21(eraseApp)]} dummy_err]} {
        error "Applet eraseApp command has not been launched ($dummy_err)"
    }

    puts "Application area erased"
}
 

Апплеты:

  /*------------------------------------------------------------------------------
 *      Linker script for running in internal SRAM on the SAMD21J18
 *----------------------------------------------------------------------------*/

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)

/* Memory Spaces Definitions */
MEMORY
{
    romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x2000
    sram (W!RX) : ORIGIN = 0x20002000, LENGTH = 0x00002000 /* sram, 4K - sizeof(romcodesram) */
}

SECTIONS
{
    /* startup code in the .isr_vector */
    .text :
    {
        . = ALIGN(4);
        _stext = .;
        KEEP(*(.isr_vector .isr_vector.*))
        *(.mailbox)
        *(.text .text.*)
        *(.rodata .rodata.*)
        *(.ramfunc .ramfunc.*)
        *(.glue_7)
        *(.glue_7t)
        *(.gcc_except_table)
        *(.rodata .rodata*)
        *(.gnu.linkonce.r.*)
        . = ALIGN(4);
        _etext = .;
    } > sram

    /* data */
    .data :
    {
        . = ALIGN(4);
        _sidata = .;
        _sdata = .;

        *(.data)
        *(.data.*)
        . = ALIGN(4);
        _edata = .;
    } > sram

    .bss (NOLOAD) : {
        _szero = .;
        *(.bss)
        . = ALIGN(4);
        _ezero = .;
    } >sram

    /* Stack in SRAM */
    _sstack = 0x20003FF0;
    /DISCARD/ : { *(.note.gnu.*) }
}
. = ALIGN(4);
end = .;
 

Комментарии:

1. При минимальных усилиях , потраченных на это, appletAddr кажется, это адрес, на который записывается обычный программный код, и appletMailboxAddr , похоже, это то место, куда вы записываете для связи с флэш-памятью. Они будут определяться сочетанием аппаратного и встроенного программного обеспечения.

2. @DonalFellows, большое вам спасибо. Не могли бы вы уточнить? Почему это работает только на appletaddr 0x20002000? Это флэш-адрес или адрес SRAM? Есть 3 прошивки. 1. прошивка загрузчика (размер 20,2 КБ) . 2. прошивка апплета (2.25 kb_sends команда через утилиту для чтения и записи на flash, обновления приложения). 3. прошивка приложения (она начинается с 0x6000 и записывается в sram) Вы знаете, как правильно их выбирать? Например, если я изменю appletAddr на 0x20001000 и appletmailboxAddr на 0x20001040, утилита вообще не будет работать.