Jump to content

Recovery from espressobin installation mistakes


Recommended Posts

I goofed-up my espressobin install and need to recover and start over.


Here is what happened (to my embarrassment):


I recently obtained a 1GB espressobin from Amazon.com.  I flashed the Armbian_5.59_Espressobin_Debian_stretch_next_4.18.6.img to a Sandisk Ultra and booted the board. The marvell>> prompt came up just fine, and I used the command bubt .flash-image-1g-1cs-800_800.bin spi usb to load the flash binary from my usb drive.  But I did not know at the time that the correct flash to use was actually flash-image-1g-1cs-1000_800.bin.  But my worse mistake was applying the script given on the instruction page, where it says: "Updated u-boot needs new default boot environment and new boot script (overwrite the one on your /boot media – needed only if you upgrade from < v5.59). This is what you need to copy/paste into u-boot prompt:".  I guess I was supposed to use the script at https://dl.armbian.com/espressobin/u-boot/bootscript/ ?   I tried to apply that script after the mistake, but it generated errors.


So now when I try to boot the board, this is the kind output I get on my minicom:

## Error: "bootcmd_" not defined
** Bad device : 0x6d00000 **
## Executing script at 06d00000
Wrong image format for "source" command

So this is a mess.  How do I go about recovering and getting back on track?





Link to comment
Share on other sites

On 9/12/2018 at 7:00 AM, thomasgrzybowski said:

How do I go about recovering and getting back on track?


You can try these settings to boot from SD or sata into 4.18.y  (at the Marvell>> prompt) - no boot script is used in this case.


If you intend to use the boot script you need to adapt /boot/boot.cmd (i.e. if you boot from sd into 4.18.y you should specify 'setenv rootdev "/dev/mmcblk1p1" ' and recompile boot.scr with 'mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr' on the command line within your OS)


Edited by ebin-dev
Link to comment
Share on other sites

Thomas, did you get your board up and running again ?

-If not, don't worry, it's not as bad as it may seem.


I'll be happy to help you get it up and running. Here's a simple overview of what happens during boot:


There are two stages: 1: The "Marvell >>" prompt is actually Uboot, the boot-loader.

If you haven't updated your boot-loader yet, you can do so from within Uboot, but you need to write the image to either a microSD card or a USB-stick first.

When you've updated your boot-loader with the correct version, you can update the boot instructions.

(The boot-instructions are actually stored in environment variables).

You can experiment with the environment variables manually at no risk of wearing out the flash-memory.

If you reboot, those experiments will have to be re-typed, as they're not saved in the SPI-flash.

When you're satisfied with your experiments, you can save the environment variables.


Normally, Armbian is written to the SD-card's first partition; this partition acts both as the boot partition and as the root file system.

(Some linux distributions have boot and rootfs on different partitions).


... I'll be happy to write in further details where needed, but it would likely be too much writing the entire boot process in a single post. ;)

Link to comment
Share on other sites

14 hours ago, thomasgrzybowski said:

^ Jens, - Thank-you so much for your instructions!  Yes, I had kind-of given-up.  I'll try again with your suggestions and let you know how it goes!

-And I haven't even begun yet. :)


I think it's important to understand the details on how the boot-process works. Once you have this knowledge, you'll know much better how to get things working if something gets messed up.


The CPU has a small on-chip boot-ROM. In this boot-ROM, there's code that cannot be altered.

This code is the code that checks the 3 jumper connections; usually these are set to load the boot-loader from SPI NOR-Flash.

If there's something messed up, you'll not get the "Marvell >>" prompt, but instead you'll get a single "> " - still, don't worry if that happens, because there is a way out.

When the boot-loader is 'trusted-firmware'-verified, then it is loaded (usually from SPI NOR-Flash as mentioned earlier, but could also be from SATA, UART or eMMC), and finally this boot-loader is executed. The boot-ROM code has now done its job.


The bootloader that was just loaded and executed is usually Uboot (it could be anything; even your own code).

This bootloader is the one that presents you with the "Marvell >>" prompt and allows you to interrupt the boot-process by pressing for instance space or return.

If the bootloader is not interrupted by a keypress within the timeout (usually 2 seconds), then it issues one single command automatically:

run bootcmd

-This 'bootcmd' is nothing but an environment variable. It contains a string that is executed by Uboot's command-interpreter.

You can issue this command to see what's in the variable:


printenv bootcmd


My 'bootcmd' looks like this:

run boot_armbian


-Yours might be different.

So another environment variable is being executed by the command-interpreter.

That environment variable holds instructions on ...

1: Get netboot images - just in case we're netbooting via PXE

2: Setup boot parameters

3: Probe the block devices, in order to find the most likely block-device to boot from (such as MicroSD-card/USB/SATA)

   Probing is usually done by the 'test' command. A boot-interface and boot-device is chosen (those are usually kept in environment variables)

   The boot-interface could for instance be "scsi" if you're booting from SATA or "mmc" if you're booting from a MicroSD card

4: Load the kernel image and emergency image (usually done by the ext4load command)

5: Execute kernel image (done by the 'iboot' command).


When step 5 is executed, Uboot finished its task and the kernel takes over.

If something goes wrong, the emergency disk image is brought up.



... If you at some point are at the "Marvell >>" prompt and want to play around, here's a few things you can try out:


If you have a SATA disk connected:

scsi scan; scsi dev 0:1

ext4ls scsi 0:1 /


If you have a MicroSD card inserted:

ext4ls mmc 0:1 /


If you have a USB block-device attached:

ext4ls usb 0:1 /

ext4ls usb 1:1 /


The number before the colon is the device number, the number after the colon is the partition.

-So if you have your rootfs on partition 12 on your SATA drive, then you could for instance ...

ext4ls scsi 0:14 /bin

... to see some of the executable files on that partition.


Note: 'scsi scan' probes the SATA interface; you will not be able to do anything useful with the device without issuing that command.


You can also set some environment variables if you wish to:

setenv myVariable "echo hello there"

printenv myVariable

echo $myVariable

run myVariable


You should be able to execute the boot instructions one-by-one until you reach 'iboot'.


Let's assume that you've found out how to make your board boot; you've written down all the commands necessary and tested that they indeed boot if you write them exactly as you have them ready (hopefully you have a terminal with copy-and-paste).

When you've got your commands tested, you can set the environment variables and save those variables to your SPI-Flash using this command:


Wait for the prompt to return. Make sure you can type on the command-line (thus you will know that the writing is done).

After that, you can just boot as usual (either by typing 'boot' or 'reset' or by pressing the reset button).

-Do *not* press the reset button while the flash-memory is being written to; that will surely mess up things. ;)


At this point, you may have tried some of the above; I expect that you're likely stuck somewhere, if so, please let me know where, so we can get you unstuck. :)

Link to comment
Share on other sites

So Jens,  I created a fresh microSD card, flashed with Armbian_5.59_Espressobin_Debian_stretch_next_4.18.6.img, and booted to the Marvell>> prompt.  Right away I see a problem:  At the Marvell>> prompt, after I enter "printenv bootcmd", I get a garbage string return:


"for target in ${boot_targets}; do run bootcmd_${tesetenv scan_dev_for_boot for prefix in ${boot_prefixes; do echo ${prefix};run boot_a_script; done". 


Should I change it to "run boot_armbian"? 




Link to comment
Share on other sites

2 hours ago, thomasgrzybowski said:

So Jens,  I created a fresh microSD card, flashed with Armbian_5.59_Espressobin_Debian_stretch_next_4.18.6.img, and booted to the Marvell>> prompt.  Right away I see a problem:  At the Marvell>> prompt, after I enter "printenv bootcmd", I get a garbage string return:


I have not seen this string configuration before, it may be the newest way that Armbian starts up - or it may be a default setup for Uboot.
It's always a good idea to explore a little before making any changes.
The 'for' command iterates through a list of words/strings.
First you want to know what's inside "boot_targets" and boot_prefixes...


printenv boot_targets boot_prefixes


If boot_targets holds a valid list (I'd expect something like 3 words), then take each of those words and supply as parameter for printenv, but prefix them with 'bootcmd_'.
Eg. if a string is 'usb' then prefix it with 'bootcmd_usb' because it looks to me like inside the bootcmd, it says 'bootcmd_$target' - something like:

printenv bootcmd_usb


I do not think the environment variable 'boot_armbian' exists on your board; I likely invented that myself, because I used to switch between the stock ubuntu and Armbian until I got Armbian working on my board.

-But I think it's a good idea to check the environment variables that the Armbian booter likely would use...
If they're all empty, it means that you'd have to enter them manually. If that's the case, I'd do something like...

printenv console get_images set_bootargs load_script get_ramfs kernel_addr ramfs_addr fdt_addr

That will print the values of those environment variables.

If those environment variables are not empty, you might get away with very little typing, otherwise you may need to 'restore' the entire Armbian boot-setting by hand.


Do this following step once only, it saves some of the old setup, in case you want to have a look at it later:

setenv orig_bootcmd "$bootcmd"
setenv orig_console "$console"

Now, let's try and restore the boot to something that resembles Armbian's usual boot sequence.
-Because I like being able to switch boot commands, I'll add an extra level in by adding the 'boot_armbian' variable.

Remember that you can verify the values of your environment variables with the 'printenv' command after setenv...


setenv console 'console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000'
setenv root 'root=/dev/nfs rw'
setenv ipaddr ''
setenv serverip ''
setenv gatewayip ''
setenv netmask ''
setenv hostname 'marvell'
setenv netdev 'eth0'
setenv rootpath 'rootpath=/srv/nfs/'
setenv extra_params
setenv bootcmd 'run boot_armbian'
setenv boot_armbian 'run get_images; run set_bootargs; run load_script; booti $kernel_addr $ramfs_addr $fdt_addr'
setenv get_images 'tftpboot $kernel_addr $image_name; tftpboot $fdt_addr $fdt_name; run get_ramfs'
setenv get_ramfs 'if test "${ramfs_name}" != "-"; then setenv ramfs_addr 0x8000000; tftpboot $ramfs_addr $ramfs_name; else setenv ramfs_addr -; fi'
setenv set_bootargs 'setenv bootargs $console $root ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:none nfsroot=$serverip:$rootpath $extra_params'
setenv load_script 'if test -e mmc 0:1 boot/boot.scr; then echo "... booting from SD"; setenv boot_interface mmc; else echo "... booting from USB"; usb start; setenv boot_interface usb; fi; if test -e $boot_interface 0:1 boot/boot.scr; then ext4load $boot_interface 0:1 0x00800000 boot/boot.scr; source; fi'
setenv kernel_addr '0x5000000'
setenv fdt_addr '0x4f00000'
setenv image_name 'boot/Image'
setenv fdt_name 'dtb'
setenv ramfs_name '-'


-As written earlier, 'saveenv' will save your environment variables to SPI-Flash, so after typing 'saveenv' above, wait until you get the "Marvell>>" prompt back; do not do anything before you see the prompt.

When you get back the prompt, make sure you have your micro-SD card inserted, then issue the following command:


-If all goes well your board should start up.

If not, I've likely made a typo somewhere, since I've typed all the above by hand, but I've checked each line more than 3 times, to make sure they're all correct - even so, there could still be errors.



Link to comment
Share on other sites

I forgot to say that it's on purpose there is no parameter for 'setenv extra_params', because this will 'unset' the variable.


One more thing: If you want information about what a command does, try typing this inside Uboot:

help booti
help ext4ls


Link to comment
Share on other sites



I see where this bootcmd comes from - from the espressobin download page here.  I was just tryin' to follow directions.





Updated u-boot needs new default boot environment and new boot script (overwrite the one on your /boot media – needed only if you upgrade from < v5.59). This is what you need to copy/paste into u-boot prompt:

env default -a
setenv fdt_addr 0x6000000
setenv kernel_addr 0x7000000
setenv loadaddr 0x8000000
setenv initrd_size 0x2000000
setenv initrd_addr 0x1100000
setenv scriptaddr 0x6d00000
setenv initrd_image uInitrd
setenv boot_targets 'usb sata mmc1 mmc0'
setenv boot_prefixes '/ /boot/'
setenv bootcmd_mmc0 'setenv devnum 0; setenv boot_interface mmc; run scan_dev_for_boot;'
setenv bootcmd_mmc1 'setenv devnum 1; setenv boot_interface mmc; run scan_dev_for_boot;'
setenv bootcmd_sata 'setenv devnum 0; scsi scan; scsi dev 0; setenv boot_interface scsi; run scan_dev_for_boot;'
setenv bootcmd_usb 'setenv devnum 0; usb start;setenv boot_interface usb; run scan_dev_for_boot;'
setenv bootcmd 'for target in ${boot_targets}; do run bootcmd_${target}; done'
setenv scan_dev_for_boot 'for prefix in ${boot_prefixes}; do echo ${prefix};run boot_a_script; done'
setenv boot_a_script 'ext4load ${boot_interface} ${devnum}:1 ${scriptaddr} ${prefix}boot.scr;source ${scriptaddr};'
# Including this line to make sure saveenv is executed.


I'll try to follow your directions instead.



Link to comment
Share on other sites

I tried posting yesterday, but when I clicked 'submit reply', the forum web-site was gone and so was everything I typed. :/


I can't reconstruct my post, but I gave an example on how little is actually needed; fortunately, I had that in my copy-and-paste buffer, so here it is:

# Set boot arguments:
setenv bootargs 'console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait loglevel=1'

# load kernel file 'boot/image' to RAM at address 0x5000000:
ext4load mmc 0:1 0x5000000 boot/image

# load fdt file to RAM at address 0x4f00000:
ext4load mmc 0:1 0x4f00000 boot/dtb/marvell/armada-3720-community.dtb

# execute kernel in RAM:
booti 0x5000000 - 0x4f00000

-Actually 'loglevel=1' is not strictly necessary, but there's no reason to be impolite. ;)

The above will only boot from partition 1 of the micro-SD card, but it's so short that it gives a fairly easy overview (in commands) of what's basically going on.


The 'bootargs' environment variable is special; it's actually read by the Linux kernel.



Anyway, I gave another example on how the environment variables could be added back in, in order to make it more readable with the stuff you might want to change at the top:

setenv iface mmc; setenv dev 0:1; setenv root '/dev/mmcblk1p1'
setenv image_name 'boot/image'
setenv fdt_name 'boot/dtb/marvell/armada-3720-community.dtb'

setenv kernel_addr 0x5000000; setenv fdt_addr 0x4f00000
setenv console 'console=ttyMV0,115200 earlycon=ar3700_uart,0xd0012000'
setenv bootargs "$console root=$root rootfstype=ext4 rootwait loglevel=1"
ext4load $iface $dev $kernel_addr $image_name
ext4load $iface $dev $fdt_addr $fdt_name
booti $kernel_addr - $fdt_addr

-As you see, it's a lot easier to see what's going on if adding environment variables with descriptive names.

The above is basically how Armbian boots. Armbian's boot, however, also loads a script-file from the boot-device called 'boot/boot.scr', which first imports environment variables from a file called 'boot/armbianEnv.txt'. This can be both helpful and confusing.

Helpful because it makes things work quickly and easily.

Confusing if you're trying to change something from your boot-prompt, because you'll keep ending up booting from the same device. ;)


Armbian's boot sequence tries to find a bootable device by first probing the SD-card and checking if there's a kernel available there. If not, then it continues to USB.

It also supports netboot. This is ideal for someone who does not want to wear out the SD-card slot (they're very fragile, because board vendors very much like to save 3 cents on picking the worst type they can find!)


We can also take the load_script environment variable from a few posts earlier ...

setenv load_script 'if test -e mmc 0:1 boot/boot.scr; then echo "... booting from SD"; setenv boot_interface mmc; else echo "... booting from USB"; usb start; setenv boot_interface usb; fi; if test -e $boot_interface 0:1 boot/boot.scr; then ext4load $boot_interface 0:1 0x00800000 boot/boot.scr; source; fi'

.... and expand it and remove the semicolons, so it's a little easier to read ...

if test -e mmc 0:1 boot/boot.scr; then
  echo "... booting from SD"
  setenv boot_interface mmc
  echo "... booting from USB"
  usb start
  setenv boot_interface usb
if test -e $boot_interface 0:1 boot/boot.scr; then
  ext4load $boot_interface 0:1 0x00800000 boot/boot.scr

... then we can add a few modifications to support SATA-boot ...

setenv script "boot/boot.scr"
if test -e mmc 0:1 $script; then
  setenv devname SD
  setenv boot_interface mmc
  usb start
  if test -e usb 0:1 $script; then
    setenv devname USB
    setenv boot_interface usb
    scsi scan
    scsi dev 0:1
    setenv devname SATA
    setenv boot_interface scsi
if test -e $boot_interface 0:1 $script; then
  echo "... booting from $devname"
  ext4load $boot_interface 0:1 0x00800000 $script

... and finally wrap it back up in one line ...

setenv load_script 'setenv script "boot/boot.scr"; if test -e mmc 0:1 $script; then setenv devname SD; setenv boot_interface mmc; else usb start; if test -e usb 0:1 $script; then; setenv devname USB; setenv boot_interface usb; else scsi scan; scsi dev 0:1; setenv devname SATA; setenv boot_interface scsi; fi; fi; if test -e $boot_interface 0:1 $script; then echo "... booting from $devname"; ext4load $boot_interface 0:1 0x00800000 $script; source; fi'

... which is basically what I use for booting from SATA (except from I do not attempt to boot from USB, since I often have my SD-card attached without wanting to boot from it.

Edited by Jens Bauer
Show that we boot from SATA. Make final load_script shorter and change 'endif' to 'fi'. Removed extraneous double-quotes. Changed to boot from mmcblk1p1.
Link to comment
Share on other sites

This topic is now closed to further replies.
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines