This documents an investigation into how an Ambian card for the Orange Pi PC was set up for booting. In summary, several things are learned:
/dev/sdc1 on /run/media/tom/bb870b9b-0835-49be-9212-62c2cc05b755 type ext4 (rw Disk /dev/sdc: 7.4 GiB, 7948206080 bytes, 15523840 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x86673d77 Device Boot Start End Sectors Size Id Type /dev/sdc1 2048 15213343 15211296 7.3G 83 LinuxNote that the first partition starts 2048 sectors into the SD card. This leaves 1M of space for the partition table, spl, and U-boot. This offset could easily be increased.
There is no uEnv.txt in "/" or "/boot". The contents of the /boot directory are:
cd /boot ls -l drwxr-xr-x 2 root root 4096 Sep 14 22:31 bin -rw-r--r-- 1 root root 6944 Sep 14 22:31 boot.bmp -rw-r--r-- 1 root root 2814 Sep 14 22:29 boot.cmd -rw-r--r-- 1 root root 2886 Sep 14 22:33 boot.scr -rw-r--r-- 1 root root 94749 Sep 14 11:29 config-3.4.112-sun8i -rw-r--r-- 1 root root 3114454 Sep 14 22:31 initrd.img-3.4.112-sun8i lrwxrwxrwx 1 root root 18 Sep 14 22:31 script.bin -> bin/orangepipc.bin -rw-r--r-- 1 root root 2119429 Sep 14 11:29 System.map-3.4.112-sun8i -rw-r--r-- 1 root root 3114518 Sep 14 22:31 uInitrd -rwxr-xr-x 1 root root 5025168 Sep 14 11:29 vmlinuz-3.4.112-sun8i lrwxrwxrwx 1 root root 21 Sep 14 22:29 zImage -> vmlinuz-3.4.112-sun8i
dd if=Armbian_5.20_Orangepipc_Debian_jessie_3.4.112.img of=/dev/sdc bs=32M 46+1 records in 46+1 records out 1562378240 bytes (1.6 GB, 1.5 GiB) copied, 185.603 s, 8.4 MB/s -- unplug and replug card mount /dev/sdc1 /mnt cd /mnt mv boot boot_ORIG mkdir bootThis ought to confuse U-boot enough so that it drops into its prompt, but interestingly enough, it drops into a network boot scenario. It does give a short countdown where I can hit any key.
U-Boot SPL 2016.09-armbian (Sep 15 2016 - 07:28:57) DRAM: 1024 MiB Trying to boot from MMC1 U-Boot 2016.09-armbian (Sep 15 2016 - 07:28:57 +0200) Allwinner Technology CPU: Allwinner H3 (SUN8I 1680) Model: Xunlong Orange Pi PC I2C: ready DRAM: 1 GiB MMC: SUNXI SD/MMC: 0 *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: phy interface0 eth0: ethernet@1c30000 Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0:1... starting USB... USB0: USB EHCI 1.00 USB1: USB OHCI 1.0 USB2: USB EHCI 1.00 USB3: USB OHCI 1.0 USB4: USB EHCI 1.00 USB5: USB OHCI 1.0 scanning bus 0 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found scanning bus 4 for devices... 1 USB Device(s) found USB device 0: unknown device BOOTP broadcast 1 BOOTP broadcast 2 BOOTP broadcast 3 BOOTP broadcast 4 DHCP client bound to address 192.168.0.69 (2268 ms) *** Warning: no boot file name; using 'C0A80045.img' Using ethernet@1c30000 device TFTP from server 192.168.0.1; our IP address is 192.168.0.69 Filename 'C0A80045.img'. Load address: 0x42000000 Loading: T T T Abort missing environment variable: pxeuuid missing environment variable: bootfile Retrieving file: pxelinux.cfg/01-02-20-26-57-ac-37 Using ethernet@1c30000 device TFTP from server 192.168.0.1; our IP address is 192.168.0.69 Filename 'pxelinux.cfg/01-02-20-26-57-ac-37'. Load address: 0x43200000Indeed, getting to the prompt is not that hard, just cycle power and immediately start typing on the keyboard:
U-Boot SPL 2016.09-armbian (Sep 15 2016 - 07:28:57) DRAM: 1024 MiB Trying to boot from MMC1 U-Boot 2016.09-armbian (Sep 15 2016 - 07:28:57 +0200) Allwinner Technology CPU: Allwinner H3 (SUN8I 1680) Model: Xunlong Orange Pi PC I2C: ready DRAM: 1 GiB MMC: SUNXI SD/MMC: 0 *** Warning - bad CRC, using default environment In: serial Out: serial Err: serial Net: phy interface0 eth0: ethernet@1c30000 Hit any key to stop autoboot: 0 => => printenv arch=arm baudrate=115200 board=sunxi board_name=sunxi boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr} boot_efi_binary=load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootarm.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf boot_net_usb_start=usb start boot_prefixes=/ /boot/ boot_script_dhcp=boot.scr.uimg boot_scripts=boot.scr.uimg boot.scr boot_targets=fel mmc0 usb0 pxe dhcp bootcmd=run distro_bootcmd bootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; setenv efi_old_vci ${bootp_vci};setenv efi_old_arch ${bootp_arch};setenv bootp_vci PXEClient:Arch:00010:UNDI:003000;setenv bootp_arch 0xa;if dhcp ${kernel_addr_r}; then tftpboot ${fdt_addr_r} dtb/${efi_fdtfile};if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r}; else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi;fi;setenv bootp_vci ${efi_old_vci};setenv bootp_arch ${efi_old_arch};setenv efi_fdtfile;setenv efi_old_arch;setenv efi_old_vci; bootcmd_fel=if test -n ${fel_booted} && test -n ${fel_scriptaddr}; then echo '(FEL boot)'; source ${fel_scriptaddr}; fi bootcmd_mmc0=setenv devnum 0; run mmc_boot bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi bootcmd_sunxi_compat=setenv root /dev/mmcblk0p3 rootwait; if ext2load mmc 0 0x44000000 uEnv.txt; then echo Loaded environment from uEnv.txt; env import -t 0x44000000 ${filesize}; fi; setenv bootargs console=${console} root=${root} ${extraargs}; ext2load mmc 0 0x43000000 script.bin && ext2load mmc 0 0x48000000 uImage && bootm 0x48000000 bootcmd_usb0=setenv devnum 0; run usb_boot bootdelay=2 bootm_size=0xa000000 console=ttyS0,115200 cpu=armv7 dfu_alt_info_ram=kernel ram 0x42000000 0x1000000;fdt ram 0x43000000 0x100000;ramdisk ram 0x43300000 0x4000000 distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done efi_dtb_prefixes=/ /dtb/ /dtb/current/ ethaddr=02:20:26:57:ac:37 fdt_addr_r=0x43000000 fdtcontroladdr=7bf3df28 fdtfile=sun8i-h3-orangepi-pc.dtb kernel_addr_r=0x42000000 load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile} mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi pxefile_addr_r=0x43200000 ramdisk_addr_r=0x43300000 scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi; scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootarm.efi; then echo Found EFI removable media binary efi/boot/bootarm.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done scriptaddr=0x43100000 serial#=020046202657ac37 soc=sunxi stderr=serial stdin=serial stdout=serial usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi Environment size: 4358/131068 bytes => help ? - alias for 'help' base - print or set address offset bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootefi - Boots an EFI payload from memory bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol bootvx - Boot vxWorks from an ELF image bootz - boot Linux zImage image from memory cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation dhcp - boot image via network using DHCP/TFTP protocol dm - Driver model low level access echo - echo args to console editenv - edit environment variable env - environment handling commands exit - exit script ext2load- load binary file from a Ext2 filesystem ext2ls - list files in a directory (default /) ext4load- load binary file from a Ext4 filesystem ext4ls - list files in a directory (default /) ext4size- determine a file's size false - do nothing, unsuccessfully fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fatsize - determine a file's size fatwrite- write file into a dos filesystem fdt - flattened device tree utility commands fstype - Look up a filesystem type go - start application at address 'addr' gpio - query and control gpio pins help - print command description/usage i2c - I2C sub-system iminfo - print header information for application image imxtract- extract a part of a multi-image itest - return true/false on integer compare load - load binary file from a filesystem loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loadx - load binary file over serial line (xmodem mode) loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range ls - list files in a directory (default /) md - memory display mdio - MDIO utility commands mii - MII utility commands mm - memory modify (auto-incrementing address) mmc - MMC sub system mmcinfo - display MMC info mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) part - disk partition related commands ping - send ICMP ECHO_REQUEST to network host printenv- print environment variables pxe - commands to get and boot from pxe files reset - Perform RESET of the CPU run - run commands in an environment variable save - save file to a filesystem saveenv - save environment variables to persistent storage setenv - set environment variables setexpr - set environment variable as the result of eval expression showvar - print local hushshell variables size - determine a file's size sleep - delay execution for some time source - run script from memory sysboot - command to get and boot from syslinux files test - minimal test like /bin/sh tftpboot- boot image via network using TFTP protocol true - do nothing, successfully usb - USB sub-system usbboot - boot from USB device version - print monitor, compiler and linker versionGetting the MAC address is a little problematic, but it is tucked away in the messages from the first boot:
Retrieving file: pxelinux.cfg/01-02-20-26-57-ac-37Using the mac address, I add an entry to the /etc/dhcpd/dhcpd.conf file on my linux machine.
host orangepi { hardware ethernet 02:20:26:57:ac:37; fixed-address 192.168.0.69; option host-name "orangepi"; server-name "trona"; filename "orange"; }Issue the command "service dhcpd restart" and try again. U-boot picks up the "filename" entry which I set to "orange". I don't have a file there yet by that name.
In passing, I will note that its default is to construct the filename "C0A80045.img", where this is the IP address 192.168.0.69 in hexadecimal.
DHCP client bound to address 192.168.0.69 (4 ms) Using ethernet@1c30000 device TFTP from server 192.168.0.5; our IP address is 192.168.0.69 Filename 'orange'. Load address: 0x42000000 Loading: * TFTP error: 'File not found' (1)I copy a file by this name into /var/lib/tftpboot and reboot the orange pi. I will note that U-boot has a "reset" command this is just the thing for this. Now I get the following:
DHCP client bound to address 192.168.0.69 (4 ms) Using ethernet@1c30000 device TFTP from server 192.168.0.5; our IP address is 192.168.0.69 Filename 'orange'. Load address: 0x42000000 Loading: ########### 904.3 KiB/s done Bytes transferred = 158396 (26abc hex) CACHE: Misaligned operation at range [42000000, 42026abc] ## Executing script at 43100000 Wrong image format for "source" commandThis is success! The size of the file I copied is indeed 158396 bytes.
-rwxr-xr-x 1 root root 158396 Dec 9 17:20 orangeMy file contains a program for an entirely different boards, so we can expect unpredicatable results. After this failure, U-boot attempts to source whatever might be at address 0x43100000, then tries loading a list of alternate executables, as follows (but loading them to 0x43200000 not 0x42000000):
Retrieving file: pxelinux.cfg/01-02-20-26-57-ac-37 Retrieving file: pxelinux.cfg/C0A80045 Retrieving file: pxelinux.cfg/C0A8004 Retrieving file: pxelinux.cfg/C0A800 Retrieving file: pxelinux.cfg/C0A80 Retrieving file: pxelinux.cfg/C0A8 Retrieving file: pxelinux.cfg/C0A Retrieving file: pxelinux.cfg/C0 Retrieving file: pxelinux.cfg/C Retrieving file: pxelinux.cfg/default-arm-sunxi Retrieving file: pxelinux.cfg/default-arm Retrieving file: pxelinux.cfg/defaultEven after building an ARM binary with a single instruction (branch to self), I get:
TFTP from server 192.168.0.5; our IP address is 192.168.0.69 Filename 'orange'. Load address: 0x42000000 Loading: # 2 KiB/s done Bytes transferred = 4 (4 hex) CACHE: Misaligned operation at range [42000000, 42000004] .... .... ## Starting EFI application at 0x42000000 ... efi_load_pe: Invalid DOS Signature ## Application terminated, r = -2It looks like the CACHE alignment message is just a warning I can ignore, but this business about an invalid DOS Signature is the real issue.
Look for a file "pe.h" with contents like:
typedef struct _IMAGE_DOS_HEADER { uint16_t e_magic; /* 00: MZ Header signature */ uint16_t e_cblp; /* 02: Bytes on last page of file */ uint16_t e_cp; /* 04: Pages in file */ uint16_t e_crlc; /* 06: Relocations */ uint16_t e_cparhdr; /* 08: Size of header in paragraphs */ uint16_t e_minalloc; /* 0a: Minimum extra paragraphs needed */ uint16_t e_maxalloc; /* 0c: Maximum extra paragraphs needed */ uint16_t e_ss; /* 0e: Initial (relative) SS value */ uint16_t e_sp; /* 10: Initial SP value */ uint16_t e_csum; /* 12: Checksum */ uint16_t e_ip; /* 14: Initial IP value */ uint16_t e_cs; /* 16: Initial (relative) CS value */ uint16_t e_lfarlc; /* 18: File address of relocation table */ uint16_t e_ovno; /* 1a: Overlay number */ uint16_t e_res[4]; /* 1c: Reserved words */ uint16_t e_oemid; /* 24: OEM identifier (for e_oeminfo) */ uint16_t e_oeminfo; /* 26: OEM information; e_oemid specific */ uint16_t e_res2[10]; /* 28: Reserved words */ uint32_t e_lfanew; /* 3c: Offset to extended header */ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; #define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ #define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ #define IMAGE_FILE_MACHINE_ARM 0x01c0 #define IMAGE_FILE_MACHINE_THUMB 0x01c2 #define IMAGE_FILE_MACHINE_ARMNT 0x01c4 #define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_FILE_MACHINE_ARM64 0xaa64 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b #define IMAGE_SUBSYSTEM_EFI_APPLICATION 10Actually, the thing to do is find the U-boot sources and/or find a way to just override the U-boot bootcmd so it does something more reasonable.
Looking at the U-boot setup, I don't think it will actually load uEnv.txt, so I really have no alternative besides rebuilding U-boot.
Tom's electronics pages / tom@mmto.org