A U-Boot Independent Standalone Application

U-Boot allows you to load your own applications at the console. The application already has the hardware interfaces available for use (u-boot does it), and everything does not need to be brought up from scratch.

It comes with a sample hello_world program at u-boot/examples/standalone/hello_world.c, which is supposed to print stuff to console. It depends on U-Boot interfaces, but by tracing back the source code, it can be easily re-written to have nothing to do with the U-Boot API.

In the end, hello_world.c:printf()’s job is to write the characters to UART’s address. Implementing this on a BeagleBone Black is pretty easy:

The ARM AM335x TRM mentions the address-offsets of all registers available with the processor. The UART0_BASE is defined at 0x44E09000. Memory mapped registers need to be kept volatile to prevent compiler optimizing them away.

Here’s the code:

Compile it similarly to U-Boot’s examples to get a .bin.

To execute it, you can either: 1) copy the SREC over serial, 2) set up TFTP or 3) put it on an sdcard

The load_address below is an env var that specifies where the application will be loaded. It can be changed when building U-Boot.
For the current build, find it from the console using

U-Boot# printenv

U-Boot# fatload mmc 0 <load_address>
[...]

The entry point’s address of the application can be found by looking at the objdump. See this if you have larger applications.
Launching it,

U-Boot# go <entry_point_address>


If you plan to write a purely standalone binary, you are required to initialize the hardware manually and provide a functioning C execution environment. It also requires information regarding placement and relocation of the text and data segments, allocation and zeroing of BSS segment and placement of the stack space. See this and this.


Transferring a .bin from openSUSE to U-Boot, or, Rightly Configuring TFTP on openSUSE

After spending a *lot* of time figuring out why I could not transfer a standalone binary to u-boot running on my BeagleBone Black, I finally discovered it was a firewall issue. This post is to save anyone in the future from suffering the same nightmare as I just went through on openSUSE 13.1.

The Problem:

I needed to put a .bin on my BBB which has U-Boot. The available options are:

Transferring the S-Record

SREC is the hex encoding of binary data generated on compilation. To load this, U-Boot provides the `loads` command at its console. You just need to pass the ASCII-Hex data from the .srec to the serial console (see this). The problem is, the speed of sending this data must be okay with the U-Boot console. Gave me a `data abort` message and my board reset.

Using TFTP

Better option: tftp. Have static IP setup for the host and the board (set env vars ipaddr and serverip on u-boot) and call tftp. It gave me this:

U-Boot# tftp
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.10.1; our IP address is 192.168.10.2
Filename 'hello_world.bin'.
Load address: 0x80200000
Loading: T T T T T T T T T T T T T T T 
Abort

(**T = Timeout.**)

Fix:

TFTP uses UDP port 69 for transfers. I needed to explicitly check “Open port in firewall” from the TFTP server config from YaST and add port 69 to Firewall->Allowed Services->UDP Ports.

 

X-Loader / MLO With a Custom Payload

X-Loader (MLO) (u-boot/common/spl/spl.c, responsible for eMMC initialization and executing the u-boot binary) first parses the image header info (u-boot/common/spl/spl.c:spl_parse_image_header) which effectively does this:

if (magic number of header == IH_MAGIC) {
  set spl_image to the detected image
}
else {
  fill in spl_image assuming u-boot.bin
}
...
call spl_image->entry_point()

IH_MAGIC is set to 0x27051956, the default magic number when creating an image with mkimage. This image can be called from within u-boot at the u-boot command line. By default, the SPL assumes a `uImage` payload and if not found, tries to launch u-boot.

Some Notes on Randomness

Judging the ‘quality’ of random data is indeed a complex statistical problem. The dieharder suite has been designed around this issue, which consists of a number of tests that establish a criteria for an RNG to be good, and fail if it isn’t met. The tests differ significantly from each other; some of these may be easier to pass than the others.

A PRNG needs to be initialized using a ‘seed’, which may be taken from the machine-available sources of entropy (/dev/random, /dev/urandom on Linux). Since it works on deterministic algorithms, for the same seed, the PRNG produces the same results on each run. So, if the seed is compromised, the adversary may be able to predict the sequence produced by the PRNG. Since /dev/random and /dev/urandom are char devices, their concurrent reads from multiple applications will preserve the uniqueness of the data received by each application. This implies that if multiple PRNGs are being initialized at the same time, each of these receives a unique seed.

The OpenSSL PRNG, on Unix-like OSes it seeds itself using data obtained by reading /dev/urandom, /dev/random and /dev/srandom (on OpenBSD), spending 10 ms on each (openssl/crypto/rand/rand_unix.c). For the PRNG to be cryptographically secure, its initial seed must not become known. This, in case of OpenSSL, implies that the external devices it reads from must be reliable sources of randomness.

For machines that lack /dev/random as an option, Entropy Gathering Daemon can be used. It is a perl script which runs in the background, calling the programs available on the machine and using their results to slowly fill its entropy pool (egd.pl:175 – 321). OpenSSL can be configured to use EGD as a source of randomness. A virtual machine running on QEMU can also be fed from EGD but this is slow due to EGD’s way of working and is being investigated. Also, if EGD is not running in the `–bottomless` mode, it often blocks when being used with QEMU. So, it is not advisable to be used as of now.

Another source of randomness could be the hardware random number generators. These claim to be cryptographically secure and unpredictable, and are often very fast. But these are only as reliable as their manufacturer. Certain Intel processors provide an instruction that they claim returns reliable random numbers. But a recent revelation indicates that this instruction may have been rigged because of influence from the NSA. Therefore, depending on an HWRNG as the only source of randomness would be a bad idea. A better option is to just add this data to the main entropy pool along with data from other sources.

Dieharder Tests on a qemu VM – 3: Results II

Continued from Dieharder Tests on a qemu VM – 2: Results

Here are the results for running dieharder on a guest not feeding on the host’s entropy (i.e. invoking qemu without the virtio-rng-pci device). The test returns WEAK at a number of places, as opposed to the previous results, indicating that the entropy supplied to it isn’t completely random. This implies that using the virtio-rng-pci device is a good choice if there are no explicit sources of randomness available to the guest.

guest:entropy_avail stayed around 160 while running. The host, when not running a vm seemed to pass the dieharder suite.

#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
stdin_input_raw|  2.62e+06  | 762187023|
#=============================================================================#
        test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
   diehard_birthdays|   0|       100|     100|0.83795012|  PASSED
      diehard_operm5|   0|   1000000|     100|0.91399772|  PASSED
  diehard_rank_32x32|   0|     40000|     100|0.99934932|   WEAK
    diehard_rank_6x8|   0|    100000|     100|0.75473508|  PASSED
   diehard_bitstream|   0|   2097152|     100|0.52888766|  PASSED
        diehard_opso|   0|   2097152|     100|0.99863189|   WEAK
        diehard_oqso|   0|   2097152|     100|0.99544153|   WEAK
         diehard_dna|   0|   2097152|     100|0.35600968|  PASSED
diehard_count_1s_str|   0|    256000|     100|0.55492562|  PASSED
diehard_count_1s_byt|   0|    256000|     100|0.93158424|  PASSED
 diehard_parking_lot|   0|     12000|     100|0.00682730|  PASSED
    diehard_2dsphere|   2|      8000|     100|0.60579818|  PASSED
    diehard_3dsphere|   3|      4000|     100|0.50801068|  PASSED
     diehard_squeeze|   0|    100000|     100|0.20780916|  PASSED
        diehard_sums|   0|       100|     100|0.03163035|  PASSED
        diehard_runs|   0|    100000|     100|0.91464960|  PASSED
        diehard_runs|   0|    100000|     100|0.76009031|  PASSED
       diehard_craps|   0|    200000|     100|0.83910125|  PASSED
       diehard_craps|   0|    200000|     100|0.17404472|  PASSED
 marsaglia_tsang_gcd|   0|  10000000|     100|0.42896571|  PASSED
 marsaglia_tsang_gcd|   0|  10000000|     100|0.34960417|  PASSED
         sts_monobit|   1|    100000|     100|0.26441569|  PASSED
            sts_runs|   2|    100000|     100|0.97799925|  PASSED
          sts_serial|   1|    100000|     100|0.99506951|   WEAK
          sts_serial|   2|    100000|     100|0.72894480|  PASSED
          sts_serial|   3|    100000|     100|0.88766272|  PASSED
          sts_serial|   3|    100000|     100|0.71821524|  PASSED
          sts_serial|   4|    100000|     100|0.27325832|  PASSED
          sts_serial|   4|    100000|     100|0.16764233|  PASSED
          sts_serial|   5|    100000|     100|0.39649567|  PASSED
          sts_serial|   5|    100000|     100|0.17208569|  PASSED
          sts_serial|   6|    100000|     100|0.75970039|  PASSED
          sts_serial|   6|    100000|     100|0.04285571|  PASSED
          sts_serial|   7|    100000|     100|0.05956044|  PASSED
          sts_serial|   7|    100000|     100|0.51915899|  PASSED
          sts_serial|   8|    100000|     100|0.02280669|  PASSED
          sts_serial|   8|    100000|     100|0.36128748|  PASSED
          sts_serial|   9|    100000|     100|0.42272524|  PASSED
          sts_serial|   9|    100000|     100|0.96531298|  PASSED
          sts_serial|  10|    100000|     100|0.90920764|  PASSED
          sts_serial|  10|    100000|     100|0.07381200|  PASSED
          sts_serial|  11|    100000|     100|0.56475893|  PASSED
          sts_serial|  11|    100000|     100|0.22136924|  PASSED
          sts_serial|  12|    100000|     100|0.63632280|  PASSED
          sts_serial|  12|    100000|     100|0.90584207|  PASSED
          sts_serial|  13|    100000|     100|0.98929282|  PASSED
          sts_serial|  13|    100000|     100|0.84940410|  PASSED
          sts_serial|  14|    100000|     100|0.51337504|  PASSED
          sts_serial|  14|    100000|     100|0.35658437|  PASSED
          sts_serial|  15|    100000|     100|0.69324168|  PASSED
          sts_serial|  15|    100000|     100|0.96847166|  PASSED
          sts_serial|  16|    100000|     100|0.90513868|  PASSED
          sts_serial|  16|    100000|     100|0.65808536|  PASSED
         rgb_bitdist|   1|    100000|     100|0.46915603|  PASSED
         rgb_bitdist|   2|    100000|     100|0.95162255|  PASSED
         rgb_bitdist|   3|    100000|     100|0.23686073|  PASSED
         rgb_bitdist|   4|    100000|     100|0.65453723|  PASSED
         rgb_bitdist|   5|    100000|     100|0.46193454|  PASSED
         rgb_bitdist|   6|    100000|     100|0.85670400|  PASSED
         rgb_bitdist|   7|    100000|     100|0.02560679|  PASSED
         rgb_bitdist|   8|    100000|     100|0.31628821|  PASSED
         rgb_bitdist|   9|    100000|     100|0.45408518|  PASSED
         rgb_bitdist|  10|    100000|     100|0.12875926|  PASSED
         rgb_bitdist|  11|    100000|     100|0.48889700|  PASSED
         rgb_bitdist|  12|    100000|     100|0.11948926|  PASSED
rgb_minimum_distance|   2|     10000|    1000|0.80584597|  PASSED
rgb_minimum_distance|   3|     10000|    1000|0.09039280|  PASSED
rgb_minimum_distance|   4|     10000|    1000|0.87310457|  PASSED
rgb_minimum_distance|   5|     10000|    1000|0.47373390|  PASSED
    rgb_permutations|   2|    100000|     100|0.97254452|  PASSED
    rgb_permutations|   3|    100000|     100|0.87507703|  PASSED
    rgb_permutations|   4|    100000|     100|0.43610221|  PASSED
    rgb_permutations|   5|    100000|     100|0.99864288|   WEAK
      rgb_lagged_sum|   0|   1000000|     100|0.58568154|  PASSED
      rgb_lagged_sum|   1|   1000000|     100|0.13875851|  PASSED
      rgb_lagged_sum|   2|   1000000|     100|0.94819967|  PASSED
      rgb_lagged_sum|   3|   1000000|     100|0.19215309|  PASSED
      rgb_lagged_sum|   4|   1000000|     100|0.57478843|  PASSED
      rgb_lagged_sum|   5|   1000000|     100|0.72827902|  PASSED
      rgb_lagged_sum|   6|   1000000|     100|0.58226183|  PASSED
      rgb_lagged_sum|   7|   1000000|     100|0.74428735|  PASSED
      rgb_lagged_sum|   8|   1000000|     100|0.56414577|  PASSED
      rgb_lagged_sum|   9|   1000000|     100|0.97272745|  PASSED
      rgb_lagged_sum|  10|   1000000|     100|0.88742338|  PASSED
      rgb_lagged_sum|  11|   1000000|     100|0.65596031|  PASSED
      rgb_lagged_sum|  12|   1000000|     100|0.31356087|  PASSED
     rgb_kstest_test|   0|     10000|    1000|0.52619545|  PASSED
     dab_bytedistrib|   0|  51200000|       1|0.77236000|  PASSED
             dab_dct| 256|     50000|       1|0.51011037|  PASSED
        dab_filltree|  32|  15000000|       1|0.57769621|  PASSED
        dab_filltree|  32|  15000000|       1|0.75930039|  PASSED
      rgb_lagged_sum|  13|   1000000|     100|0.32785148|  PASSED
       dab_filltree2|   0|   5000000|       1|0.31084546|  PASSED
       dab_filltree2|   1|   5000000|       1|0.13226028|  PASSED
      rgb_lagged_sum|  14|   1000000|     100|0.27358978|  PASSED
        dab_monobit2|  12|  65000000|       1|0.51741346|  PASSED

Dieharder Tests on a qemu VM – 2: Results

Continued from Dieharder Tests on a qemu VM – 1: Setup

I kept a log of the entropy on the host and the guest every 45 seconds using

$ watch -n 45 "cat /proc/sys/kernel/random/entropy_avail \
    | tee -a entropy_log.txt"

The time variation for both the entropies came to be (gnuplot!):

Host Entropy
Host Entropy

The sudden spikes are for some user activity occurring in that period. If left inactive, entropy stays around 170.

Guest Entropy
Guest Entropy

The tests take a long time to complete (The whole set took me around four hours, and left me with an insanely overheated machine!)

Here is what dieharder returned:

#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
stdin_input_raw|  2.47e+06  |1371137764|
#=============================================================================#
        test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
   diehard_birthdays|   0|       100|     100|0.86862896|  PASSED  
      diehard_operm5|   0|   1000000|     100|0.09873382|  PASSED  
  diehard_rank_32x32|   0|     40000|     100|0.39552041|  PASSED  
    diehard_rank_6x8|   0|    100000|     100|0.39218537|  PASSED  
   diehard_bitstream|   0|   2097152|     100|0.85712947|  PASSED  
        diehard_opso|   0|   2097152|     100|0.65776718|  PASSED  
        diehard_oqso|   0|   2097152|     100|0.19758082|  PASSED  
         diehard_dna|   0|   2097152|     100|0.27897319|  PASSED  
diehard_count_1s_str|   0|    256000|     100|0.83681957|  PASSED  
diehard_count_1s_byt|   0|    256000|     100|0.96680935|  PASSED  
 diehard_parking_lot|   0|     12000|     100|0.66719833|  PASSED  
    diehard_2dsphere|   2|      8000|     100|0.37057540|  PASSED  
    diehard_3dsphere|   3|      4000|     100|0.70806712|  PASSED  
     diehard_squeeze|   0|    100000|     100|0.53966681|  PASSED  
        diehard_sums|   0|       100|     100|0.02822295|  PASSED  
        diehard_runs|   0|    100000|     100|0.61266236|  PASSED  
        diehard_runs|   0|    100000|     100|0.91609332|  PASSED  
       diehard_craps|   0|    200000|     100|0.60334904|  PASSED  
       diehard_craps|   0|    200000|     100|0.99227047|  PASSED  
 marsaglia_tsang_gcd|   0|  10000000|     100|0.19080480|  PASSED  
 marsaglia_tsang_gcd|   0|  10000000|     100|0.90001880|  PASSED  
         sts_monobit|   1|    100000|     100|0.36930675|  PASSED  
            sts_runs|   2|    100000|     100|0.08069978|  PASSED  
          sts_serial|   1|    100000|     100|0.29611422|  PASSED  
          sts_serial|   2|    100000|     100|0.67776624|  PASSED  
          sts_serial|   3|    100000|     100|0.99390925|  PASSED  
          sts_serial|   3|    100000|     100|0.81490996|  PASSED  
          sts_serial|   4|    100000|     100|0.43241627|  PASSED  
          sts_serial|   4|    100000|     100|0.00546390|  PASSED  
          sts_serial|   5|    100000|     100|0.39402393|  PASSED  
          sts_serial|   5|    100000|     100|0.34953549|  PASSED  
          sts_serial|   6|    100000|     100|0.76867851|  PASSED  
          sts_serial|   6|    100000|     100|0.89268070|  PASSED  
          sts_serial|   7|    100000|     100|0.95917368|  PASSED  
          sts_serial|   7|    100000|     100|0.92632458|  PASSED  
          sts_serial|   8|    100000|     100|0.95194884|  PASSED  
          sts_serial|   8|    100000|     100|0.92765999|  PASSED  
          sts_serial|   9|    100000|     100|0.60964619|  PASSED  
          sts_serial|   9|    100000|     100|0.19973194|  PASSED  
          sts_serial|  10|    100000|     100|0.30045937|  PASSED  
          sts_serial|  10|    100000|     100|0.28046316|  PASSED  
          sts_serial|  11|    100000|     100|0.39479056|  PASSED  
          sts_serial|  11|    100000|     100|0.93644086|  PASSED  
          sts_serial|  12|    100000|     100|0.39082598|  PASSED  
          sts_serial|  12|    100000|     100|0.12484222|  PASSED
          sts_serial|  13|    100000|     100|0.88230291|  PASSED  
          sts_serial|  13|    100000|     100|0.28399163|  PASSED  
          sts_serial|  14|    100000|     100|0.30412173|  PASSED  
          sts_serial|  14|    100000|     100|0.38876109|  PASSED  
          sts_serial|  15|    100000|     100|0.32394068|  PASSED  
          sts_serial|  15|    100000|     100|0.06754801|  PASSED  
          sts_serial|  16|    100000|     100|0.27237626|  PASSED  
          sts_serial|  16|    100000|     100|0.33825605|  PASSED  
         rgb_bitdist|   1|    100000|     100|0.96008377|  PASSED  
         rgb_bitdist|   2|    100000|     100|0.70661060|  PASSED  
         rgb_bitdist|   3|    100000|     100|0.79542560|  PASSED  
         rgb_bitdist|   4|    100000|     100|0.68858655|  PASSED  
         rgb_bitdist|   5|    100000|     100|0.90823465|  PASSED  
         rgb_bitdist|   6|    100000|     100|0.91443686|  PASSED  
         rgb_bitdist|   7|    100000|     100|0.79858739|  PASSED  
         rgb_bitdist|   8|    100000|     100|0.95913929|  PASSED  
         rgb_bitdist|   9|    100000|     100|0.60175923|  PASSED  
         rgb_bitdist|  10|    100000|     100|0.96923959|  PASSED  
         rgb_bitdist|  11|    100000|     100|0.15208339|  PASSED  
         rgb_bitdist|  12|    100000|     100|0.26135873|  PASSED 
rgb_minimum_distance|   2|     10000|    1000|0.77861169|  PASSED  
rgb_minimum_distance|   3|     10000|    1000|0.00212982|   WEAK   
rgb_minimum_distance|   4|     10000|    1000|0.31023346|  PASSED  
rgb_minimum_distance|   5|     10000|    1000|0.40301991|  PASSED  
    rgb_permutations|   2|    100000|     100|0.50882956|  PASSED  
    rgb_permutations|   3|    100000|     100|0.31787007|  PASSED  
    rgb_permutations|   4|    100000|     100|0.47652641|  PASSED  
    rgb_permutations|   5|    100000|     100|0.92450336|  PASSED  
      rgb_lagged_sum|   0|   1000000|     100|0.26333265|  PASSED  
      rgb_lagged_sum|   1|   1000000|     100|0.75116347|  PASSED  
      rgb_lagged_sum|   2|   1000000|     100|0.13950855|  PASSED  
      rgb_lagged_sum|   3|   1000000|     100|0.93462392|  PASSED  
      rgb_lagged_sum|   4|   1000000|     100|0.99538753|   WEAK   
      rgb_lagged_sum|   5|   1000000|     100|0.84015937|  PASSED  
      rgb_lagged_sum|   6|   1000000|     100|0.39294482|  PASSED  
      rgb_lagged_sum|   7|   1000000|     100|0.95276622|  PASSED  
      rgb_lagged_sum|   8|   1000000|     100|0.38480211|  PASSED  
      rgb_lagged_sum|   9|   1000000|     100|0.12822922|  PASSED  
      rgb_lagged_sum|  10|   1000000|     100|0.75884102|  PASSED  
      rgb_lagged_sum|  11|   1000000|     100|0.81236992|  PASSED  
      rgb_lagged_sum|  12|   1000000|     100|0.47372927|  PASSED
     rgb_kstest_test|   0|     10000|    1000|0.41691852|  PASSED  
     dab_bytedistrib|   0|  51200000|       1|0.50909808|  PASSED  
             dab_dct| 256|     50000|       1|0.63160301|  PASSED  
        dab_filltree|  32|  15000000|       1|0.00756161|  PASSED  
        dab_filltree|  32|  15000000|       1|0.27671644|  PASSED
       dab_filltree2|   0|   5000000|       1|0.44752389|  PASSED  
       dab_filltree2|   1|   5000000|       1|0.78668278|  PASSED
        dab_monobit2|  12|  65000000|       1|0.08419938|  PASSED

Which is fairly good! I should try to find out what happens if you’re not feeding entropy from the host, and simply run dieharder.

Dieharder Tests on a qemu VM – 1: Setup

Diehard suite is a collection of tests for random number generators. I recently used it on a virtual machine feeding on the /dev/urandom of it’s host.

The Setup:

Used Debian 7.2 as both the host and the guest. The virtio-rng-pci virtual device allows feeding entropy from the host to the guest since qemu 1.3.

Invoking qemu with

-device virtio-rng-pci

attaches host:/dev/random to guest:/dev/hwrng. This is usually slow (tried it; too slow on my laptop), because /dev/random blocks. So I used the following:

$ qemu-system-x86_64 debian.qcow -L pc-bios -enable-kvm \
  -object rng-random,filename=/dev/urandom,id=rng0 \
  -device virtio-rng-pci,rng=rng0

which ties the host:/dev/urandom to the guest:/dev/hwrng. To verify that this is happening, run

$ cat /sys/devices/virtual/misc/hw_random/rng_available
$ cat /sys/devices/virtual/misc/hw_random/rng_current

These should return `virtio`

Now that guest:/dev/hwrng is available, it can be used to feed other sources of entropy on the guest. This can be done using rngd – a daemon available with the rng-tools package. The file /etc/default/rng-tools lets you provide the source of input to rngd. Adding

HRNGDEVICE=/dev/hwrng

to the file and restarting the daemon

$ /etc/init.d/rng-tools start

begins mixing entropy into the kernel’s pool. If you were running low on entropy, there is a noticeable rise in guest:entropy_avail sometime after this, host:entropy_avail falls a little.

You can find an opensource implementation of the diehard tests here.

$ cat /dev/urandom | dieharder -a -g 200

begins dieharder with all (-a) tests on the data obtained from stdin (-g 200), i.e. the data piped from /dev/urandom

Keep looking at entropy_avail and notice a drop. (Reading from it too much also depletes entropy, so read less often).