doc: how to use QEMU to test big-endian build
Document the process of using buildroot to build a big-endian binary of OpenOCD and using QEMU User Mode Emulation for running the big-endian binary on a little-endian host PC. Change-Id: Ic5fe26e353a4cf69e57af3c23ae7fa4b25347b2b Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: https://review.openocd.org/c/openocd/+/6968 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
parent
63cc08f6a2
commit
424f9f6796
|
@ -0,0 +1,27 @@
|
||||||
|
BR2_armeb=y
|
||||||
|
BR2_cortex_a7=y
|
||||||
|
BR2_TOOLCHAIN_EXTERNAL=y
|
||||||
|
BR2_PACKAGE_OPENOCD=y
|
||||||
|
BR2_PACKAGE_OPENOCD_FTDI=y
|
||||||
|
BR2_PACKAGE_OPENOCD_STLINK=y
|
||||||
|
BR2_PACKAGE_OPENOCD_TI_ICDI=y
|
||||||
|
BR2_PACKAGE_OPENOCD_ULINK=y
|
||||||
|
BR2_PACKAGE_OPENOCD_UBLASTER2=y
|
||||||
|
BR2_PACKAGE_OPENOCD_JLINK=y
|
||||||
|
BR2_PACKAGE_OPENOCD_OSDBM=y
|
||||||
|
BR2_PACKAGE_OPENOCD_OPENDOUS=y
|
||||||
|
BR2_PACKAGE_OPENOCD_AICE=y
|
||||||
|
BR2_PACKAGE_OPENOCD_VSLLINK=y
|
||||||
|
BR2_PACKAGE_OPENOCD_USBPROG=y
|
||||||
|
BR2_PACKAGE_OPENOCD_RLINK=y
|
||||||
|
BR2_PACKAGE_OPENOCD_ARMEW=y
|
||||||
|
BR2_PACKAGE_OPENOCD_XDS110=y
|
||||||
|
BR2_PACKAGE_OPENOCD_PARPORT=y
|
||||||
|
BR2_PACKAGE_OPENOCD_VPI=y
|
||||||
|
BR2_PACKAGE_OPENOCD_UBLASTER=y
|
||||||
|
BR2_PACKAGE_OPENOCD_AMTJT=y
|
||||||
|
BR2_PACKAGE_OPENOCD_GW16012=y
|
||||||
|
BR2_PACKAGE_OPENOCD_PRESTO=y
|
||||||
|
BR2_PACKAGE_OPENOCD_OPENJTAG=y
|
||||||
|
BR2_PACKAGE_OPENOCD_BUSPIRATE=y
|
||||||
|
BR2_PACKAGE_OPENOCD_SYSFS=y
|
|
@ -0,0 +1,197 @@
|
||||||
|
/** @page endianness About endianness
|
||||||
|
|
||||||
|
OpenOCD has to potentially deal with different endianness between:
|
||||||
|
- the host PC endianness;
|
||||||
|
- the data endianness during communication between host and adapter;
|
||||||
|
- the target CPU endianness.
|
||||||
|
|
||||||
|
The whole OpenOCD code should be written to handle any endianness
|
||||||
|
mismatch and should run on either little and big endian hosts.
|
||||||
|
|
||||||
|
Big-endian host PC are becoming less and less common since Apple™ has
|
||||||
|
switched away from big-endian PowerPC™ in favor of little-endian intel
|
||||||
|
X86™.
|
||||||
|
|
||||||
|
The lack of commercial big-endian hosts makes hard testing OpenOCD correctness
|
||||||
|
on big-endian hosts. Running OpenOCD on low-cost commercial routers based on
|
||||||
|
big-endian MIPS is possible, but it's tricky to properly setup the system and
|
||||||
|
the cross-compiling environment.
|
||||||
|
|
||||||
|
In next sections there are two example on how to compile and test OpenOCD in an
|
||||||
|
emulated big-endian environment.
|
||||||
|
|
||||||
|
|
||||||
|
@section endianness_helpers OpenOCD API for handling endianness
|
||||||
|
|
||||||
|
Use the following OpenOCD API to handle endianness conversions:
|
||||||
|
- host endianness to/from little endian:
|
||||||
|
- le_to_h_u64(), le_to_h_u32(), le_to_h_u16();
|
||||||
|
- h_u64_to_le(), h_u32_to_le(), h_u16_to_le();
|
||||||
|
- buf_get_u32(), buf_get_u64();
|
||||||
|
- buf_set_u32(), buf_set_u64();
|
||||||
|
- host endianness to/from big endian:
|
||||||
|
- be_to_h_u64(), be_to_h_u32(), be_to_h_u16();
|
||||||
|
- h_u64_to_be(), h_u32_to_be(), h_u16_to_be();
|
||||||
|
- host endianness to/from target endianness:
|
||||||
|
- target_read_u64(), target_read_u32(), target_read_u16();
|
||||||
|
- target_write_u64(), target_write_u32(), target_write_u16();
|
||||||
|
- target_write_phys_u64(), target_write_phys_u32(), target_write_phys_u16();
|
||||||
|
- target_buffer_get_u64(), target_buffer_get_u32(), target_buffer_get_u24(), target_buffer_get_u16();
|
||||||
|
- target_buffer_set_u64(), target_buffer_set_u32(), target_buffer_set_u24(), target_buffer_set_u16();
|
||||||
|
- byte swap:
|
||||||
|
- buf_bswap32(), buf_bswap16().
|
||||||
|
|
||||||
|
|
||||||
|
@section endianness_docker Use dockers to run different endianness
|
||||||
|
|
||||||
|
|
||||||
|
Docker can run a full Linux image that includes the toolchain through QEMU
|
||||||
|
emulator.
|
||||||
|
By selecting a big-endian image, it's possible to compile and execute OpenOCD
|
||||||
|
in big-endian.
|
||||||
|
There are, so far, not many options for big-endian images; s390x is one of the
|
||||||
|
few available.
|
||||||
|
|
||||||
|
To be expanded.
|
||||||
|
|
||||||
|
User should:
|
||||||
|
- install docker;
|
||||||
|
- download the big-endian image;
|
||||||
|
- run the image in docker;
|
||||||
|
- download, in the image, the OpenOCD code to test;
|
||||||
|
- recompile OpenOCD code in the image;
|
||||||
|
- run OpenOCD binary in the image.
|
||||||
|
|
||||||
|
From https://github.com/multiarch/qemu-user-static
|
||||||
|
|
||||||
|
@code{.unparsed}
|
||||||
|
docker run --rm -t s390x/ubuntu bash
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@section endianness_qemu Use buildroot and QEMU to run different endianness
|
||||||
|
|
||||||
|
QEMU User Mode Emulation is an efficient method to launch, on host's CPU,
|
||||||
|
applications compiled for another CPU and/or for different endianness.
|
||||||
|
It works either on Linux and BSD. More info available on
|
||||||
|
https://www.qemu.org/docs/master/user/index.html
|
||||||
|
|
||||||
|
With QEMU User Mode Emulation is thus possible running, on a commonly available
|
||||||
|
little-endian X86 Linux host, OpenOCD compiled for a big-endian host.
|
||||||
|
|
||||||
|
The following example will show how to use buildroot to:
|
||||||
|
- build big-endian toolchain and libraries;
|
||||||
|
- compile OpenOCD for big-endian;
|
||||||
|
- run the big-endian OpenOCD on little-endian Linux PC.
|
||||||
|
|
||||||
|
The example will use ARM Cortex-A7 big-endian only because I personally feel
|
||||||
|
comfortable reading ARM assembly during debug. User can select other CPU
|
||||||
|
architectures, as this does not impact the result.
|
||||||
|
|
||||||
|
A similar method can be used to test OpenOCD compiled for 32 vs 64 bit host.
|
||||||
|
|
||||||
|
@note
|
||||||
|
- the version of autotools locally installer in your Linux host can be
|
||||||
|
incompatible with the version of autotools used by buildroot. This can cause
|
||||||
|
the build to fail if buildroot has to run its autotools on a partially
|
||||||
|
configured OpenOCD folder. Use either a clean copy of OpenOCD code in 2., or
|
||||||
|
run "./bootstrap" in OpenOCD folder to prevent buildroot from using its own
|
||||||
|
autotools;
|
||||||
|
- the configuration tool in 4. and 5. matches the version of OpenOCD used by
|
||||||
|
buildroot. Some new driver could be not listed in. OpenOCD will build every
|
||||||
|
driver that is not disabled and with satisfied dependencies. If the driver
|
||||||
|
you plan to use is not listed, try a first build and check OpenOCD with
|
||||||
|
command "adapter list", then try to hack the buildroot files Config.in and
|
||||||
|
openocd.mk in folder package/openocd/ and use "make openocd-reconfigure" to
|
||||||
|
rerun the build starting with configuration;
|
||||||
|
- using pre-built toolchains, you need 2GB of disk space for buildroot build.
|
||||||
|
To also rebuild the toolchains you will need ~5GB and much longer time for
|
||||||
|
the first build (it takes ~2 hour on my crap 10+ years old laptop);
|
||||||
|
- you need to install few tools for buildroot dependency, listed in
|
||||||
|
https://buildroot.org/downloads/manual/manual.html#requirement ;
|
||||||
|
- you need to install qemu-armeb. On Arch Linux it's in package qemu-arch-extra;
|
||||||
|
on Ubuntu/debian it's packaged in qemu-user.
|
||||||
|
Buildroot can also be configured to build qemu for the host, if you prefer,
|
||||||
|
by enabling BR2_PACKAGE_HOST_QEMU_LINUX_USER_MODE, but this takes longer
|
||||||
|
compile time;
|
||||||
|
- don't use qemu-system-arm, as it emulates a complete system and requires a
|
||||||
|
fully bootable ARM image;
|
||||||
|
- while QEMU User Mode Emulation is available for both Linux and BSD, buildroot
|
||||||
|
only builds binaries for Linux target. This example can only be used with
|
||||||
|
Linux hosts emulating the Linux target.
|
||||||
|
|
||||||
|
|
||||||
|
Steps to run big-endian OpenOCD on little-endian host Linux PC:
|
||||||
|
|
||||||
|
1. Get buildroot source. Today's latest version is "2022.02":
|
||||||
|
@code{.unparsed}
|
||||||
|
wget https://buildroot.org/downloads/buildroot-2022.02.tar.xz
|
||||||
|
tar xf buildroot-2022.02.tar.xz
|
||||||
|
cd buildroot-2022.02
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
2. Override the source repo for OpenOCD in order to build your own code version
|
||||||
|
in place of the default OpenOCD release version:
|
||||||
|
@code{.unparsed}
|
||||||
|
echo OPENOCD_OVERRIDE_SRCDIR=/home/me/openocd.git >> local.mk
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
3. Copy default config for OpenOCD big-endian. This used:
|
||||||
|
- ARM Cortex-A7 big-endian target,
|
||||||
|
- external Linaro armeb toolchain (to speed up first build),
|
||||||
|
- OpenOCD all configure options enabled.
|
||||||
|
|
||||||
|
@code{.unparsed}
|
||||||
|
cp $OPENOCD_OVERRIDE_SRCDIR/contrib/buildroot/openocd_be_defconfig configs/
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
4. Configure buildroot with default config for OpenOCD big-endian:
|
||||||
|
@code{.unparsed}
|
||||||
|
make openocd_be_defconfig
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
5. Optional, change buildroot configuration:
|
||||||
|
@code{.unparsed}
|
||||||
|
make menuconfig
|
||||||
|
@endcode
|
||||||
|
These are the options selected with default config for OpenOCD big-endian:
|
||||||
|
@code{.unparsed}
|
||||||
|
Target options --->
|
||||||
|
Target Architecture --->
|
||||||
|
ARM (big endian)
|
||||||
|
Target Architecture Variant --->
|
||||||
|
cortex-A7
|
||||||
|
Toolchain --->
|
||||||
|
Toolchain type --->
|
||||||
|
External toolchain
|
||||||
|
Toolchain --->
|
||||||
|
Linaro armeb 2018.05
|
||||||
|
Toolchain origin --->
|
||||||
|
Toolchain to be downloaded and installed
|
||||||
|
Target packages --->
|
||||||
|
Hardware handling --->
|
||||||
|
openocd
|
||||||
|
All adapters selected
|
||||||
|
@endcode
|
||||||
|
Save and exit
|
||||||
|
|
||||||
|
6. Build (and take a long coffee break ...):
|
||||||
|
@code{.unparsed}
|
||||||
|
make openocd
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
7. Execute big-endian OpenOCD:
|
||||||
|
@code{.unparsed}
|
||||||
|
cd output/target
|
||||||
|
qemu-armeb -cpu cortex-a7 -L . usr/bin/openocd -s usr/share/openocd/scripts/ -f board/st_nucleo_f4.cfg
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
8. Optional, to rebuild after any source code modification in ${OPENOCD_OVERRIDE_SRCDIR}:
|
||||||
|
@code{.unparsed}
|
||||||
|
make openocd-rebuild
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
|
/** @file
|
||||||
|
This file contains the @ref endianness page.
|
||||||
|
*/
|
|
@ -19,6 +19,8 @@ check the mailing list archives to find the status of your feature (or bug).
|
||||||
- The @subpage bugs page contains the content of the BUGS file, which
|
- The @subpage bugs page contains the content of the BUGS file, which
|
||||||
provides instructions for submitting bug reports to the maintainers.
|
provides instructions for submitting bug reports to the maintainers.
|
||||||
- The @subpage releases page describes the project's release process.
|
- The @subpage releases page describes the project's release process.
|
||||||
|
- The @subpage endianness provides hints about writing and testing
|
||||||
|
endianness independent code for OpenOCD.
|
||||||
|
|
||||||
@ref primer provide introductory materials for new developers on various
|
@ref primer provide introductory materials for new developers on various
|
||||||
specific topics.
|
specific topics.
|
||||||
|
|
Loading…
Reference in New Issue