How to compare two memory location using CMP command in u-boot - u-boot

I'm trying to compare two memory locations using the u-boot (CMP) command. I've u-boot-swap.bin which is flashed at the MTD partition (/dev/mtd2). There is the same u-boot-swap.bin file present at MMC. I want to see if the u-boot flashed at the MTD location (/dev/mtd2) & one present at MMC partition is the same or not.
I tried following commands,
Read u-boot-swap.bin from /dev/mtd2 to memory address 0x81000000
=> sf read 0x81000000 0x40000 0xc0000
device 0 offset 0x40000, size 0xc0000
SF: 786432 bytes # 0x40000 Read: OK
Read u-boot-swap.bin from MMC to memory address 0x82000000
=> ext4load mmc 0:2 0x82000000 /boot/u-boot-swap.bin
445512 bytes read in 144 ms (2.9 MiB/s)
Then I tried to compare two memory locations using cmp command, But I'm getting mismatch
=> cmp 0x81000000 0x82000000 445512
word at 0x8105c7dc (0x76203033) != word at 0x8205c7dc (0x76203130)
Total of 94711 word(s) were the same
=> cmp 0x81000000 0x82000000 786432
word at 0x8105c7dc (0x76203033) != word at 0x8205c7dc (0x76203130)
Total of 94711 word(s) were the same
What I'm doing wrong here? How to compare two memory location?

First of all, some u-boot commands assume arguments are hexadecimal values, you should try replacing cmp 0x81000000 0x82000000 445512 by cmp 0x81000000 0x82000000 0x0006cc48 (0x0006cc48= 445512d) or use the $filesize variable which is populated after loading a file.
This being said, if you have the original u-boot-swap.bin available, a convenient way to understand what exactly is going on would be to compare the content of your file with the content of the two memory area you loaded using sf and ext4load. This can be done by computing an MD5 hash on the file and the two memory areas (I created one for the purpose of my answer):
On my PC:
dd if=/dev/random of=u-boot-swap.bin bs=445512 count=1
ls -l u-boot-swap.bin
md5sum -b u-boot-swap.bin
def7d2bd063bc9d383889a4fc148aff6 *u-boot-swap.bin
On the system running u-boot, loading u-boot-swap.bin and verifying the MD5 hash computed on the memory area that received u-boot-swap.bin has the same MD5 hash:
=> loadb
## Ready for binary (kermit) download to 0x80800000 at 115200 bps...
CACHE: Misaligned operation at range [80800000, 8086cc48]
## Total Size = 0x0006cc48 = 445512 Bytes
## Start Addr = 0x80800000
=> hash md5 0x80800000 0x0006cc48
md5 for 80800000 ... 8086cc47 ==> def7d2bd063bc9d383889a4fc148aff6
The two computed MD5 hashes are the same.
If you don't have the original file available, you wil just be able to compute the MD5 hashes on the two memory areas, but you will not be able to know which one (if any) matches the content of your original file. On my system:
# Copying file content previously loaded at `0x80800000` to `0x81000000` and `0x820000001 :
cp.b 80800000 0x81000000 0x0006cc48
cp.b 80800000 0x82000000 0x0006cc48
hash md5 0x81000000 0x0006cc48
md5 for 81000000 ... 8106cc47 ==> def7d2bd063bc9d383889a4fc148aff6
hash md5 0x82000000 0x0006cc48
md5 for 82000000 ... 8206cc47 ==> def7d2bd063bc9d383889a4fc148aff6
If your u-boot does not have the hash command available, you may use crc32 instead - on my PC:
sudo apt install libarchive-zip-perl
crc32 u-boot-swap.bin
b952fb8d
On my system running u-boot:
crc32 80800000 0x0006cc48
crc32 for 80800000 ... 8086cc47 ==> b952fb8d
crc32 0x81000000 0x0006cc48
crc32 for 81000000 ... 8106cc47 ==> b952fb8d
crc32 0x82000000 0x0006cc48
crc32 for 82000000 ... 8206cc47 ==> b952fb8d
In the case you would not have any of the hash and crc32 commands available, I would strongly suggest to rebuild your u-boot with the hash command and update it on your target system.

Related

Contiguous Hex file generation using GCC

I have a Hex file for STM32F427 that was built using GCC(gcc-arm-none-eabi) version 4.6 that had contiguous memory addresses. I wrote boot loader for loading that hex file and also added checksum capability to make sure Hex file is correct before starting the application.
Snippet of Hex file:
:1005C80018460AF02FFE07F5A64202F1D00207F5F9
:1005D8008E4303F1A803104640F6C821C2F2000179
:1005E8001A460BF053F907F5A64303F1D003184652
:1005F8000BF068F907F5A64303F1E80340F6FC1091
:10060800C2F2000019463BF087FF07F5A64303F145
:10061800E80318464FF47A710EF092FC07F5A643EA
:1006280003F1E80318460EF03DFC034607F5A64221
:1006380002F1E0021046194601F0F2FC07F56A5390
As you can see all the addresses are sequential. Then we changed the compiler to version 4.8 and i got the same type of Hex file.
But now we used compiler version 6.2 and the Hex file generated is not contiguous. It is somewhat like this:
:10016000B9BC0C08B9BC0C08B9BC0C08B9BC0C086B
:10017000B9BC0C08B9BC0C08B9BC0C08B9BC0C085B
:08018000B9BC0C08B9BC0C0865
:1001900081F0004102E000BF83F0004330B54FEA38
:1001A00041044FEA430594EA050F08BF90EA020FA5
As you can see after 0188 it is starting at 0190 means rest of 8 bytes(0189 to 018F) are 0xFF as they are not flashed.
Now boot loader is kind of dumb where we just pass the starting address and no of bytes to calculate the checksum.
Is there a way to make hex file in contiguous way as compiler 4.6 and compiler 4.8? the code is same in all the three times.
If post-processing the hex file is an option, you can consider using the IntelHex python library. This lets you manipulate hex file data (i.e. ignoring the 'markup'; record type, address, checksum etc) rather than as lines, will for instance create output with the correct line checksum.
A fast way to get this up and running could be to use the bundled convenience scripts hex2bin.py and bin2hex.py:
python hex2bin.py --pad=FF noncontiguous.hex tmp.bin
python bin2hex.py tmp.bin contiguous.hex
The first line converts the input file noncontiguous.hex to a binary file, padding it with FF where there is no data. The second line converts it the binary file back to a hex file.
The result would be
:08018000B9BC0C08B9BC0C0865
becomes
:10018000B9BC0C08B9BC0C08FFFFFFFFFFFFFFFF65
As you can see, padding bytes are added where the input doesn't have any data, equivalent to writing the input file to the device and reading it back out. Bytes that are in the input file are kept the same - and at the same address.
The checksum is also correct as changing the length byte from 0x08 to 0x10 compensates for the extra 0xFF bytes. If you padded with something else, IntelHex would output the correct checksum
You can skip the the creation of a temporary file by piping these: omit tmp.bin in the first line and replacing it with - in the second line:
python hex2bin.py --pad=FF noncontiguous.hex | python bin2hex.py - contiguous.hex
An alternative way could be to have a base file with all FF and use the hexmerge.py convenience script to merge gcc's output onto it with --overlap=replace
The longer, more flexible way, would be to implement your own tool using the IntelHex API. I've used this to good effect in situations similar to yours - tweak hex files to satisfy tools that are costly to change, but only handle hex files the way they were when the tool was written.
One of many possible ways:
Make your hex file with v6.2, e.g., foo.hex.
Postprocess it with this Perl oneliner:
perl -pe 'if(m/^:(..)(.*)$/) { my $rest=16-hex($1); $_ = ":10" . $2 . ("FF" x $rest) . "\n"; }' foo.hex > foo2.hex
Now foo2.hex will have all 16-byte lines
Note: all this does is FF-pad to 0x10 bytes. It doesn't check addresses or anything else.
Explanation
perl -pe '<some script>' <input file> runs <some script> for each line of <input file>, and prints the result. The script is:
if(m/^:(..)(.*)$/) { # grab the existing byte count into $1
my $rest=16 - hex($1); # how many bytes of 0xFF we need
$_ = ":10" . $2 . ("FF" x $rest) . "\n"; # make the new 16-byte line
# existing bytes-^^ ^^^^^^^^^^^^^^-pad bytes
}
Another solution is to change the linker script to ensure the preceding .isr_vector section ends on a 16 byte alignment, as the mapfile reveals that the following .text section is 16 byte aligned.
This will ensure there is no unprogrammed flash bytes between the two sections
You can use bincopy to fill all empty space with 0xff.
$ pip install bincopy
$ bincopy fill foo.hex
Use the -gap-fill option of objcopy, e.g.:
arm-none-eabi-objcopy --gap-fill 0xFF -O ihex firmware.elf firmware.hex

Load a binary into flash memory using gdb

I'd like to flash a binary file into my ARM MCU flash memory using gdb.
Currently I'm able to load an elf like this:
# arm-none-eabi-gdb --command=flash.gdb "myfirmware.elf"
# cat flash.gdb
set confirm off
target remote 127.0.0.1:7224
monitor reset
load
detach
quit
Basically the load command is good at loading elf sections to the right addresses.
However to put multiple firmware in the MCU flash memory, I'd like to send a complete binary image.
In order to test it, I made a zero.bin image (containing nothing but 0):
# hexdump zero.bin
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0020000
# arm-none-eabi-gdb
(gdb) target remote 127.0.0.1:7224
(gdb) mon reset halt
(gdb) mon reset init
(gdb) set arm fallback-mode auto
(gdb) set debug arm
(gdb) restore zero.bin binary 0x0
Restoring binary file zero.bin into memory (0x0 to 0x20000)
Writing to flash memory forbidden in this context
(gdb) info mem
Using memory regions provided by the target.
Num Enb Low Addr High Addr Attrs
0 y 0x00000000 0x00020000 flash blocksize 0x800 nocache
1 y 0x00020000 0x100000000 rw nocache
(gdb) delete mem 1
warning: Switching to manual control of memory regions; use "mem auto" to fetch regions from the target again.
(gdb) delete mem 0
(gdb) mem 0 0x100000000 rw nocache
(gdb) info mem
Using user-defined memory regions.
Num Enb Low Addr High Addr Attrs
1 y 0x00000000 0x100000000 rw nocache
(gdb) restore zero.bin binary 0x0
Restoring binary file zero.bin into memory (0x0 to 0x20000)
(gdb) x/10 0x0
0x0: 0x20003000 0x00003c5d 0x00003c7d 0x00003c7d
0x10: 0x00000000 0x00000000 0x00000000 0x00000000
0x20: 0x00000000 0x00000000
So this doesn't seem to work, as you can see in 0x0 it should be full of '0' but it still contains my previous firmware (the vector table actually)
What do I miss? Or maybe there is another way to load a binary using gdb?
If you are using OpenOCD,
mon flash write_bank <num> <file_name> <offset>
should help you.
For example, if your flash starts at 0x400000,
mon flash write_bank 0 zero.bin 0x100000
will write the zero.bin file at 0x500000, assuming that address is writable.
You can't delete memory region. Because GDB uses vFlashWrite packet for writing to flash memory and M or X packets for writing to RAM.
I know only one way to write binary data to flash memory using gdb.
You need to transform your binary image to elf-file with one single .data section.
powerpc-objcopy -I binary -O elf32-powerpc -B PowerPC -S zero.bin zero.elf
For checking your new elf-file use readelf.
powerpc-readelf -h -t zero.elf
In the end just use load command with flash base address, because this elf-file has not any address information. (or you can use --change-addresses 0x0 option with objcopy)
load zero.elf 0x0
I checked this on PowerPC. GDB version is 8.1.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=powerpc-eabi".

Can I easily compile u-boot with more commands for arm versatile bp

I have compiled u-boot from u-boot-2013.01.y branch for versatilebp board (arm), and I need fatload command that is not present in this configuation.
I'm running u-boot under qemu
DRAM: 128 MiB
WARNING: Caches not enabled
Using default environment
In: serial
Out: serial
Err: serial
Net: SMC91111-0
Warning: SMC91111-0 using MAC address from net device
VersatilePB # fat
Unknown command 'fat' - try 'help'
VersatilePB # help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
cmp - memory compare
cp - memory copy
crc32 - checksum calculation
dhcp - boot image via network using DHCP/TFTP protocol
env - environment handling commands
erase - erase FLASH memory
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print command description/usage
iminfo - print header information for application image
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
mtest - simple RAM read/write test
mw - memory write (fill)
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
setenv - set environment variables
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version
VersatilePB #
I need fatload to load file containing image of fat filesystem containing kernel of freebsd. Can I somehow change compile config for that board to compile u-boot with fatload command? Or it's just not possible/not supported for that board?
Having done more or less exactly this for a Versatile AB, it's most certainly possible. The simplest way is to find where that board's command set is defined, and hack in the commands you want by defining the relevant CONFIG_CMD_* symbols. In this case, that place is include/configs/versatile.h.
Looking at my checkout of 2015.07, I seem to have added, among others (I think I was trying to convince the MMC to work at the time), these lines:
#define CONFIG_CMD_FAT
#define CONFIG_DOS_PARTITION 1

Reverse enginering a Linux based USB camera

I bought an IP camera on which is installed proprietary software (no HTTP server).
This prevents me to integrate it into my home network.
I want to replace the software (ELF closed source) by the motion package I already use and add some features.
I have no particular system competence and it's been over a week since I travel the net to learn but I can not get out.
I have access to the U-boot console (USB-TTL adapter) and telnet (root).
The webcam has a SD card reader that I could use if I need space.
I started by making a backup of the three partitions (with dd).
I unzipped the file mtdblock2 (binwalk -e). Which generates a classical Linux tree with links to Busybox, some binary system and proprietary software.
I tried to unzip mtdblock1 which generates zImage.
The decompression zImage generates two directories and one file (console).
Yet I need the kernel modules that are in it. What to do?
I also want to get the kernel compilation settings, is this possible?
I unpacked the firmware available on the manufacturer's website.
It contains only updating the ELF, one .so file and some Bash scripts.
At first I thought the three partitions directly migrate to Qemu.
But if I understand this is not possible because the memory addresses are hard-coded into the kernel.
I understand good?
So I think I have one solution: build a new kernel and rebuild a rootfs from scratch.
Is this only solution?
I started playing with Buildroot but I can not find the configuration file for board based on Hisilicon Hi3518.
I looked bad or is it useless?
For my first test I used board/qemu/arm-versatile. This is the right choice?
This will not prevent me from migrating to the physical machine?
For testing, if I managed to rebuild a kernel and rootfs I would install these partitions on the SD not to break anything.
For this, it is "sufficient" to modify kernel parameters (in bootargs variable) is that right?
So I don't need to rebuild a U-boat partition for my device?
In short, you guessed I ask myself a lot of questions (yet others but "one" thing at a time).
I need advice about whether I take the right road.
Please, if I am talking nonsense feel free to correct me.
If you have ideas or subjects of reflection I'm interested.
# cat /proc/cpuinfo
Processor : ARM926EJ-S rev 5 (v5l)
BogoMIPS : 218.72
Features : swp half thumb fastmult edsp java
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant : 0x0
CPU part : 0x926
CPU revision : 5
Hardware : hi3518
Revision : 0000
Serial : 0000000000000000
# cat /proc/mtd
dev: size erasesize name
mtd0: 00100000 00010000 "boot"
mtd1: 00300000 00010000 "kernel"
mtd2: 00c00000 00010000 "rootfs"
# binwalk mtdblock0
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
122044 0x1DCBC CRC32 polynomial table, little endian
# binwalk mtdblock1
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 uImage header, header size: 64 bytes, header CRC: 0x853F419E, created: 2014-07-22 02:45:04, image size: 2890840 bytes, Data Address: 0x80008000, Entry Point: 0x80008000, data CRC: 0xB24E77CA, OS: Linux, CPU: ARM, image type: OS Kernel Image, compression type: none, image name: "Linux-3.0.8"
22608 0x5850 gzip compressed data, maximum compression, from Unix, NULL date:
# binwalk zImage
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
113732 0x1BC44 ASCII cpio archive (SVR4 with no CRC), file name: "dev", file name length: "0x00000004", file size: "0x00000000"
113848 0x1BCB8 ASCII cpio archive (SVR4 with no CRC), file name: "dev/console", file name length: "0x0000000C", file size: "0x00000000"
113972 0x1BD34 ASCII cpio archive (SVR4 with no CRC), file name: "root", file name length: "0x00000005", file size: "0x00000000"
114088 0x1BDA8 ASCII cpio archive (SVR4 with no CRC), file name: "TRAILER!!!", file name length: "0x0000000B", file size: "0x00000000"
1903753 0x1D0C89 Certificate in DER format (x509 v3), header length: 4, sequence length: 1284
4188800 0x3FEA80 Linux kernel version "3.0.8 (cwen#ubuntu) (gcc version 4.4.1 (Hisilicon_v100(gcc4.4-290+uclibc_0.9.32.1+eabi+linuxpthread)) ) #1 Tue Jul 22 10:45:00 H"
4403540 0x433154 CRC32 polynomial table, little endian
5053435 0x4D1BFB Unix path: /mtd/devices/hisfc350/hisfc350_spi_gd25qxxx.c
5054731 0x4D210B Unix path: /mtd/devices/hisfc350/hisfc350.c
5058939 0x4D317B Unix path: /net/wireless/rt2x00/rt2x00dev.c
5059323 0x4D32FB Unix path: /net/wireless/rt2x00/rt2x00config.c
5060683 0x4D384B Unix path: /net/wireless/rt2x00/rt2x00usb.c
5060851 0x4D38F3 Unix path: /net/wireless/rt2x00/rt2x00.h
5061171 0x4D3A33 Unix path: /net/wireless/rt2x00/rt73usb.c
5081107 0x4D8813 Unix path: /S70/S75/505V/F505/F707/F717/P8
5102399 0x4DDB3F Unix path: /mmc/host/himciv100/himci.c
5141264 0x4E7310 Neighborly text, "NeighborSolicits/ipv6/inet6_hashtables.c"
5141284 0x4E7324 Neighborly text, "NeighborAdvertisementses.c"
# binwalk mtdblock2
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 JFFS2 filesystem, little endian
722980 0xB0824 JFFS2 filesystem, little endian
732282 0xB2C7A Zlib compressed data, compressed
737031 0xB3F07 Zlib compressed data, compressed
738287 0xB43EF Zlib compressed data, compressed
.... most other lines in the same genre
IP Camera QQZM N5063
http://www.zmvideo.com/product/detail.php?id=60
Firmware
http://bbs.zmmcu.com/forum.php?mod=attachment&aid=MzU2fDBiY2M4NDdjfDE0MTkxMTEzODl8MzQ4fDIwMzc%3D
First of all, you do not want to replace U-Boot as this may render your device unbootable. On the U-Boot console, check if you can boot from the SD card mmc rescan 0; fatload mmc 0 ${loadaddr} uImage or from the network dhcp ${loadaddr} ${serverip}:uImage. You'll need to look for documentation for these commands to get more help.
But perhaps you don't even need to replace the kernel. You already know it's a 3.0.8 kernel, so you can build a userspace for this kernel version. And any proprietary modules that are used by it can be lifted from the jffs2 filesystem. On your telnet session, do lsmod to find out which modules are loaded. You can mount an SD card and copy them to it. The modules are located in /lib/modules/3.0.8.
So you probably don't even need to build a kernel in buildroot, only the rootfs. First, check in the telnet session which filesystems are supported: cat /proc/filesystems. Then choose the appropriate filesystem in the buildroot configuration. For the target architecture, choose arm926t. And select the 3.0 kernel headers in the toolchain configuration, or choose the Arago ARMv5 2011.09 external toolchain (it has old kernel headers).
As remarked by artless noise, you don't need to test it in qemu, since the SD card is safe.

In a compressed PE must the virtual size of the data section match the raw size?

In working with a compressed PE (Windows console EXE) that has a file alignment and section alignment of 4 bytes, I notice that if virtual size and raw size of the sections match, then the program loads, but if virtual size of the data section, the last section, does not match then Windows refuses to load it, even though by the specification you should be able to have a virtual size larger than a raw size.
Is this some kind of hidden constraint on compressed PEs?
I have pasted a dumpbin /headers of the exe below:
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file ba42x.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
14C machine (x86)
2 number of sections
50AABC14 time date stamp Mon Nov 19 18:09:08 2012
0 file pointer to symbol table
0 number of symbols
60 size of optional header
10F characteristics
Relocations stripped
Executable
Line numbers stripped
Symbols stripped
32 bit word machine
OPTIONAL HEADER VALUES
10B magic # (PE32)
2.03 linker version
BD0 size of code
5000 size of initialized data
0 size of uninitialized data
CC entry point (004000CC)
CC base of code
C9C base of data
400000 image base (00400000 to 00403FFF)
4 section alignment
4 file alignment
4.00 operating system version
0.00 image version
4.00 subsystem version
0 Win32 version
4000 size of image
CC size of headers
0 checksum
3 subsystem (Windows CUI)
0 DLL characteristics
10000 size of stack reserve
1000 size of stack commit
0 size of heap reserve
0 size of heap commit
0 loader flags
0 number of directories
SECTION HEADER #1
.text name
BD0 virtual size
CC virtual address (004000CC to 00400C9B)
BD0 size of raw data
CC file pointer to raw data (000000CC to 00000C9B)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
E0000020 flags
Code
Execute Read Write
SECTION HEADER #2
.data name
3102 virtual size
C9C virtual address (00400C9C to 00403D9D)
3102 size of raw data
C9C file pointer to raw data (00000C9C to 00003D9D)
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write
Summary
3104 .data
BD0 .text
For example if you change the virtual size of the above .data section to 3106 the program will not load, even though the size of initialized data (0x5000) is more than enough to accomodate the additional memory.
No, there are not special constraints related to compressed images, since as long as your image is PE compliant, the loader does not care about the compression. Compression is handled by the stub, not the loader.
Can you provide your image for further analysis?
Just by looking at the output of dumpbin, the image looks unusual..There are no directory at all, pretty strange. It looks like the issue with the loader is not directly related to the alignement, but malformation of the image file. Did you try to have a look at your image file using other PE tools (e.g. PeStudio, CFF Explorer..?)

Resources