iMX6 get U-Boot to temporarily boot another U-Boot - embedded

First some background:
We have the following setup in our iMX6-based embedded system. There are two U-Boot partitions and two system (Linux) partitions. Currently we use only the first U-Boot partition and it uses a standard method for selecting, running and (if need be) rolling back the system partitions.
We are now looking into a similar scheme for upgrading U-Boot itself (this will happen very rarely but we do want the ability to do this without having to return the devices to base).
However, this is more fraught with danger because, once you tell the iMX6 device to boot from the alternate U-Boot partition, that's it - there's no U-Boot/watchdog combo that will revert to the previous one if boot fails, so a bad update runs a serious risk of bricking the device until we can return it to base for repair (a costly option which is why we're trying to mitigate it as much as possible).
The method chosen is a two-step U-Boot install procedure, consisting of 'write' and 'activate'. It relies on our ability to successfully figure out which U-Boot partition will be run if the device reboots (the selected one) and which is currently being run (the booted one). We've got this bit sorted out already.
But the bit that we're missing is the ability for UBoot to transfer control to the other UBoot partition under some circumstances. We got it doing different actions based solely on the UBoot environment as follows:
First, mmcboot has a prefix added so that it checks for the control transfer, specifically it's set to run ub_xfer_chk ; <original content of mmcboot>.
Secondly, we have a variable ub_xfer_flag normally set to 0.
Thirdly, we have the checking function ub_xfer_chk, defined as:
if test ${ub_xfer_flag} -eq 1 ; then
echo Soft-booting other UBoot...
setenv ub_xfer_flag 0
saveenv
weave_magic
fi
The weave_magic code is where we are having trouble :-) The idea is that this will load the other UBoot partition into memory (at our CONFIS_SYS_TEXT_BASE of 0x1780000) and execute it as if the actual device had done it.
We've tested the meat of this solution by using reset in place of weave_magic and it successfully restarts the device once, so we're certain we can make it safe.
My specific question then is :how can I convince U-Boot to load a second copy from another partition and run it?
The two UBoot partitions live in the /dev/mmcblk3boot0 and /dev/mmcblk3boot1 devices accessible from the system partition and are 2M files, including the 1K lead-in header and a fair bit of padding at the end.
Update:
We have actually had some success and managed to load an IMX image from the boot partition with the command:
ext4load mmc ${mmcdev}:${mmcpart} 0x17800000 ${bootdir}/u-boot.imx
but, when trying to execute it with:
go 0x17800000
we get an illegal instruction and immediate reboot:
pc : [<17800070>] lr : [<4ff83c64>]
sp : 4f579ac0 ip : 00000030 fp : 4f57be58
r10: 00000002 r9 : 4f579efc r8 : 4ffbe2b0
r7 : 4f57be68 r6 : 17800000 r5 : fffff200 r4 : 000002cc
r3 : 17800000 r2 : 4f57be6c r1 : 4f57be6c r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...
So I'm guessing that's not executable code at the start of that file. Any ideas on where to go from here?

The actual code in the IMX file is not at the beginning. You can discover this fact by using the excellent on-line disassembler with armv5 big-endian no-thumb architecture to figure out that the bytes at the beginning frequently give you invalid and/or not-very-sensible code:
ldtdmi a1, [a1], -a2 ; <UNPREDICTABLE>
strne a1, [a1, a1]
andeq a1, a1, a1
ldrbne pc, [pc, -ip, lsr #8]! ; <UNPREDICTABLE>
In any case, the data at the start of the IMX file is known to be header information (the d1 at the start is a "magic" marker indicating the IVT header and there should also be a DCD block after that. However, even beyond the IVT and DCD blocks (based on their purported lengths in the header fields), the code is not sensible.
However, there's viable information at offset 0xc00 following a large chunk of 0x00 bytes:
00000be0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000bf0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000c00: 0f00 00ea 14f0 9fe5 14f0 9fe5 14f0 9fe5 ................
00000c10: 14f0 9fe5 14f0 9fe5 14f0 9fe5 14f0 9fe5 ................
Putting the hex bytes at offset 0xc00 into the disassembler, and adjusting for areas that are skipped by branches, shows both valid and sane ARM code.
And, indeed, stripping the IMX file with:
dd if=u-boot.imx bs=1 skip=3072 of=ub-at-c00.imx
should give you a file you can boot with:
ext4load mmc ${mmcdev}:${mmcpart} 0x17800000 ${bootdir}/ub-at-c00.imx
go 0x17800000
When we do this, it outputs:
U-Boot 2014.04 (Nov 07 2018 - 19:05:32)
CPU: Freescale i.MX6Q rev1.5 at 792 MHz
CPU: Temperature 32 C, calibration data: 0x5764e169
Reset cause: unknown reset
Board: DTI BRD0208 (Spitfire I) 05/01/2017
I2C: ready
DRAM: 1 GiB
We know this is the newer UBoot simply because the normal one we're using outputs an October date rather than a November one.
Unfotunately, it hangs at that point, with the watchdog timer eventually kicking in and rebooting back to the original UBoot but I suspect that has to do with UBoot not liking the current state of the device (i.e., it doesn't like initialising it twice).
So we'll have to figure out how to convince it to do so but at least we've gotten it booting another copy of itself, which is what the question was about.

Related

where does the VxWorks console store data

i was using the console for resolving a "errno" like this:
-> strerror(0x23)
value = 22279888 = 0x153f6d0
-> d 0x153f6d0
NOTE: memory values are displayed in hexadecimal.
0x0153f6d0: 5f53 7265 6e72 5f6f 4e45 544f 5553 0050 *S_errno_ENOTSUP.*
0x0153f6e0: 0000 0000 0000 0000 0000 0000 0000 0000 *................*
...
0x0153f7c0: 0000 0000 0000 0000 0000 0000 0000 0000 *................*
value = 0 = 0x0
Also, if i create a new variable:
-> a=6
New symbol "a" added to kernel symbol table.
a = 0x45446f60: value = 6 = 0x6
Now it is stored and available.
But now i am wondering where are those bytes saved?
Does the console make a mem allocation in the background or has it already allocated some RAM for those purposes?
Should i be concerned where this is going to be saved?
I guess those data is stored until reboot and eating up mem as long as i am working with the console.
I took a look into "Kernel Shell User's Guide" but couln't find an answer.
(VxWorks 7.0)
strerror returns pointer to error text by error number. Error text isn't some dynamic string, it's predefined constant known before compilation starts, so it must be stored in .data segment along with all other constants, next to all other initialized data. Whenever you call strerror with the same param, you get the same address of the same memory area, feel free to try.
Creating new variable is a different thing, it actually allocates memory from the heap the same way malloc/new does. If you call malloc for small amount of data (e.g. 16 bytes) right after creating new variable, you might get pointer really close to the address of new variable. And even more, you can call free &a from console to correctly release memory back, no error should appear.
You can actually study memory map if you want to
Start and size of stack/heap should be determined somewhere within your project configuration
You can ask linker to generate .map file like this and check segments addresses in it.
So either way you'll be able to guess memory section by pointer value
Note, I worked with older versions of VxWorks only (5.5 which has ), so this might not be inaccurate, but the main idea should be OK.

STM32 Atollic TrueSTUDIO - Graphical view of the Memory

I'm using Atollic TrueSTUDIO for STM32 as an Eclipse Based IDE to perform Digital Signal Processing on audio signal. I'm looking for a way to plot an array (16 bits audio samples) from RAM memory. For the moment I'm using :
The memory View
The SWV real time data time line
None of this tools are powerful to analyse signal on an array, and it doesn't have to be on real time : Just ploting an array after reaching a breakpoint.
Is there an Eclipse Plugin or some other ways to do this ?
I'm considering to export the RAM memory and in a file and plot it in Matlab, but it seems really inapropriate for such a simple thing.
Thanks for any advices
In Atollic, you can easily attach gdb commands to breakpoints. Doing this, allows you to automaticly dump any variables. Additionally, you can execute an external programm once afterwards, to plot the content of the dumped variable.
To do so, goto breakpoint properties and create a new action. Select "Debugger Command Action" and use dump binary value x.bin x to dump variable x to file x.bin
You can also start a python script from the breakpoint to plot the data.
Use an additonal "External Tool Action" and select your python location. Make sure to select your current Working Dictonary. Use the arguments to pass the full path of the python file. The following file will import a float array and plot it.
import struct
import numpy as np
import matplotlib.pyplot as plt
import os
def readBinaryDump(filename):
result = []
N=8
with open(filename,'rb') as f:
while(True):
b = f.read(4*N);
if len(b) ==0:
break
fn = "f"*N
result.append(struct.unpack(fn,b))
result = np.array(result)
return result.ravel()
plt.plot(readBinaryDump("x.bin"))
Don't forget to add the actions to the current breakpoint. Now once the breakpoint is reached, the variable should be dumped and plotted automaticly.
While it's surprising nothing could be embeded in Atollic/Eclipse, I followed the idea of writing an specific application. Here are the steps I used :
Dump Memory :
Debug your software
Stop on a BreakPoint
View > Memory > Export Button > Format : "Plain Text"
The file representing a sine wawe looks like this :
00 00 3E 00 7D 00 BC 00 FB 00 39 01 78 01
B7 01 F6 01 34 02 73 02 B2 02 F0 02 2F 03
You should read these int16 samples like this :
1. 0x0000
2. 0x003E
3. 0x007D
4. etc...
Write this Matlab script :
fileID = fopen('your_file','r');
samples = textscan(fileID,'%s')
fclose(fileID);
samples = samples{1};
words = strcat(samples(2:2:end,1), samples(1:2:end,1));
values = typecast(uint16(hex2dec(words)),'int16');
plot(values) ;
The sinus wave plotted in Matlab
While there aren't any Eclipse plugins that would do what you're asking for that I'm personally aware of, there's STM Studio whose main purpose is displaying variables in real-time. It parses your ELF file to get the available variables, so the effort to at least give it a try should be minimal.
It's available here: https://www.st.com/en/development-tools/stm-studio-stm32.html
ST-Link is required to run it.
Write the simple app in C#. Use semi hosting to dump the memory to the text file. Open it and display.
Recently I had problem with MEMS-es and this was written in less than one hour. IMO (In My Opinion) it is easier to write program which will visualize the data instead of wasting hours or days searching for the ready made one:

Crashes in ole32!COIDTable::ThreadCleanup ... NetworkItemFactory!FDBackgroundThreadHandler

Since last week, Word and Excel are often crashing, even on very simple documents. Just now, Firefox also crashed. What can I do to repair it or find the real root cause?
I have already repaired Office installation using the Setup. All regular updates should be installed. Laptop is rebooted every day.
I have configured WinDbg to attach and this is what I get. I also have a dump, so if you need more information, I can still get it. Here's info from my first dump of Word:
0:020> .exr -1
ExceptionAddress: 11fdf91c
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000008
Parameter[1]: 11fdf91c
Attempt to execute non-executable address 11fdf91c
0:020> kb
ChildEBP RetAddr Args to Child
WARNING: Frame IP not in any known module. Following frames may be wrong.
11fdf91c 75d05d3f 00000008 0dc0bbe8 fffffffe 0x11fdf91c
11fdfacc 75d38f82 bf3079e6 0dc0bbe8 00000000 ole32!COIDTable::ThreadCleanup+0xcb [d:\w7rtm\com\ole32\com\dcomrem\idobj.cxx # 1760]
11fdfb10 75d38ec3 00000000 11fdfb60 75e37724 ole32!FinishShutdown+0x9d [d:\w7rtm\com\ole32\com\class\compobj.cxx # 1035]
11fdfb30 75d2bac3 00000000 75d309ad 0dc0bbe8 ole32!ApartmentUninitialize+0x96 [d:\w7rtm\com\ole32\com\class\compobj.cxx # 1291]
11fdfb48 75d388e8 11fdfb60 00000000 00000000 ole32!wCoUninitialize+0x153 [d:\w7rtm\com\ole32\com\class\compobj.cxx # 2766]
11fdfb64 6e77314a 11fdfbf4 75f043c0 0b179b08 ole32!CoUninitialize+0x72 [d:\w7rtm\com\ole32\com\class\compobj.cxx # 2620]
11fdfb6c 75f043c0 0b179b08 00000000 00000000 NetworkItemFactory!FDBackgroundThreadHandler+0x21
11fdfbf4 75bf336a 0da0f624 11fdfc40 773a9f72 SHLWAPI!WrapperThreadProc+0x1b5
11fdfc00 773a9f72 0da0f624 66709c63 00000000 kernel32!BaseThreadInitThunk+0xe
11fdfc40 773a9f45 75f042ed 0da0f624 ffffffff ntdll!__RtlUserThreadStart+0x70
11fdfc58 00000000 75f042ed 0da0f624 00000000 ntdll!_RtlUserThreadStart+0x1b
0:020> vertarget
Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
kernel32.dll version: 6.1.7601.18229 (win7sp1_gdr.130801-1533)
Machine Name:
Debug session time: Wed Feb 5 14:55:55.241 2014 (UTC + 1:00)
System Uptime: 0 days 3:46:03.386
Process Uptime: 0 days 0:05:08.582
Kernel time: 0 days 0:00:03.822
User time: 0 days 0:00:11.528
If I recall correctly, it was related to a VOIP software called Netphone Client from Deutsche Telekom, which includes itself into other applications via a COM object.
Therefore this was exactly as projected by Hans Passant in the comments:
You are buried inside the COM plumbing with a clear hint that its internal state is corrupted. This is an environmental problem, some kind of DLL that gets injected into the process and screws things up. Long before the crash occurs so you'll have very little hope of diagnosing it with a debugger. Find the common source of the problem from the modules list. Suspect any shell extension, anti-malware, any utility similar to Dropbox. Use SysInternals' AutoRuns to disable them.
I don't remember how exactly I found the culprit, but I finally used a physical VOIP phone instead of the software + headset.

copying kernel and uboot into sdcard

I have a Freescale I.MX ARM board for which I am preparing the bootloader, kernel and Root filesystem on the sdcard.
I am a little confused about the order in which I partition and copy my files into sdcard. Let us say I have an empty sdcard 4GB size. I used gparted to first parition it into:
Firts partition 400 MB size as FAT32 system. this is my boot partition
Second partition is the rest of the card as ext3. This is my root file system partition.
Let us say my sdcard is under /dev/sdb.
Now I have seen many documents differing slightly in the way of copying the boot files.
Which is the right way?
Method 1:
(without mounting sdb partitions:
sudo dd if=u-boot.bin of=/dev/sdb bs=512 seek=2
sudo dd if=uImage of=/dev/sdb bs=512 seek=2
Mount sdb2 for copying rootfs:
mount /dev/sdb2 /mnt/rootfs
copy rootfs:
tar -xf tarfile /mnt/rootfs
Method 2:
Mount sdb1 boot partition:
mount /dev/sdb1 /mnt/boot
copy uboot and kernel:
cp u-boot.bin /mnt/boot/
cp uImage /mnt/boot/
Then copy rootfs as above!
Which is the correct one. I tried two but the sddcard is not even booting.
When I tried method 1, the card boot up until it says the rootfs is not found in the partition. I removed the card and inserted and found that the first fat 32 partition is somehow 'destroyed' as it says 'unallocated' on gparted.
Please help.
You need to mark first partition as bootable.
Check your first partition details in gparted or disk utility.
From disk utility you cab mark a partition bootable. by selecting specific partition and going into 'more action' option --> 'edit partition type'.
below is script to flash binaries onto SD card for my
Arndale OCTA board. You can see the placement of bootloader binaries:
BL1
dd iflag=dsync oflag=dsync if=arndale_octa.bl1.bin of=/dev/sde bs=512 seek=1
BL2
dd iflag=dsync oflag=dsync if=../arndale_octa.bl2.bin of=/dev/sde bs=512 seek=31
uboot
dd iflag=dsync oflag=dsync if=u-boot.bin of=/dev/sde bs=512 seek=63
kernel and trust software , ....
Please notes:
1) The partition table is at SDcard offset 0 (seek 0), then you have to run:fdisk /dev/sde
and create paratiions that does not overlapped with blocks ocppuied by kernel or trust software.
2) add the "dsync" option in dd command to gaurantee every written data is immediately flushed into SD card
In the most of the cases, imx processor requires bootloader at 0x400 offset. So whatever you are doing for u-boot is correct, you need to use dd command for that.
sudo dd if=u-boot.bin of=/dev/sdb bs=512 seek=2
While partitioning the sd card, Make sure that you are keeping enough room for u-boot image. So start your 1st bootable partition at let's say 1 MB offset.
You can simply copy your uImage and environment variables (uEnv.txt or boot.scr) through cp command.
For rootfs also, You can follow the same steps as kernel.

Weird pcap header of byte sequence 0a 0d 0d 0a created on Mac?

I have a PCAP file that was created on a Mac with mergecap that can be parsed on a Mac with Apple's libpcap but cannot be parsed on a Linux system. combined file has an extra 16-byte header that contains 0a 0d 0d 0a 78 00 00 00 before the 4d 3c 2b 1a intro that's common in pcap files. Here is a hex dump:
0000000: 0a0d 0d0a 7800 0000 4d3c 2b1a 0100 0000 ....x...M<+.....
0000010: ffff ffff ffff ffff 0100 4700 4669 6c65 ..........G.File
0000020: 2063 7265 6174 6564 2062 7920 6d65 7267 created by merg
0000030: 696e 673a 200a 4669 6c65 313a 2037 2e70 ing: .File1: 7.p
0000040: 6361 7020 0a46 696c 6532 3a20 362e 7063 cap .File2: 6.pc
0000050: 6170 200a 4669 6c65 333a 2034 2e70 6361 ap .File3: 4.pca
0000060: 7020 0a00 0400 0800 6d65 7267 6563 6170 p ......mergecap
Does anybody know what this is? or how I can read it on a Linux system with libpcap?
I have a PCAP file
No, you don't. You have a pcap-ng file.
that can be parsed on a Mac with Apple's libpcap
libpcap 1.1.0 and later can also read some pcap-ng files (the pcap API only allows a file to have one link-layer header type, one snapshot length, and one byte order, so only pcap-ng files where all sections have the same byte order and all interfaces have the same link-layer header type and snapshot length are supported), and OS X Snow Leopard and later have a libpcap based on 1.1.x, so they can read those files.
(OS X Mountain Lion and later have tweaked libpcap to allow it to write pcap-ng files as well; the -P flag makes tcpdump write out pcap-ng files, with text comments attached to some outgoing packets indicating the process ID and process name of the process that sent them - pcap-ng allows text comments to be attached to packets.)
but cannot be parsed on a Linux system
Your Linux system probably has an older libpcap version. (Note: do not be confused by Debian and Debian derivatives calling the libpcap package "libpcap0.8" - they're not still using libpcap 0.8.)
combined file has an extra 16-byte header that contains 0a 0d 0d 0a 78 00 00 00
A pcap-ng file is a sequence of "blocks" that start with a 4-byte block type and a 4-byte length, both in the byte order of the host that wrote them.
They're divided into "sections", each one beginning with a "Section Header Block" (SHB); the block type for the SHB is 0x0a0d0d0a, which is byte-order-independent (so that you don't have to know the byte order to read the SHB) and contains carriage returns and line feeds (so that if the file is, for example, transferred between a UN*X system and a Windows system by a tool that thinks it's transferring a text file and that "helpfully" tries to fix line endings, the SHB magic number will be damaged and it will be obvious that the file was corrupted by being transferred in that fashion; think of it as the equivalent of a shock indicator).
The 0x78000000 is the length; what follows it is the "byte-order magic" field, which is 0x1A2B3C4D (which is not the same as the 0xA1B2C3D4 magic number for pcap files), and which serves the same purposes as the pcap magic number, namely:
it lets code identify that the file is a pcap-ng file
it lets code determine the byte order of the section.
(No, you don't need to know the length before looking for the pcap magic number; once you've found the magic number, you then check the length to make sure it's at least 28 and, if it's less than or equal to 28, you reject the block as not being valid.)
Does anybody know what this is?
A (little-endian) pcap-ng file.
or how I can read it on a Linux system with libpcap?
Either read it on a Linux system with a newer version of libpcap (which may mean a newer version of whatever distribution you're using, or may just mean doing an update if that will get you a 1.1.0 or later version of libpcap), read it with Wireshark or TShark (which have their own library for reading capture files, which supports the native pcap and pcap-ng formats, as well as a lot of other formats), or download a newer version of libpcap from tcpdump.org, build it, install it, and then build whatever other tools need to read pcap-ng files with that version of libpcap rather than the one that comes with the system.
Newer versions of Wireshark write pcap-ng files by default, including in tools such as mergecap; you can get them to write pcap files with a flag argument of -F pcap.