[BPI-R2] How to build an Ubuntu/Debian SD image from scratch

I checked these 2 images with a hex editor: the first is the header with the SDMMC_BOOT signature and the pointer to the 2nd header (0x00000200). It’s exactly 440 bytes long and obviously intended to overwrite the code section in the master boot record created with parted, but not the partition table (which is located at the end of the 512 byte MBR. after the 440 bytes).

The second image is the 2nd header with the signature BRLYT and the pointer to the preloader address (0x00000800), and some other values (i don’t know the meaning).

yes, it’s not working that way :wink:

ok, thx, good hint.

1 Like

have separated the basic SD-Setup from the OS-Part and added to my wiki: https://www.fw-web.de/dokuwiki/doku.php?id=en:bpi-r2:storage#sd-card

Perfect, thx.

Btw: I tried the updated 4.14 kernel from your repository with Ubuntu 18.04. Works like a charm :smiley: I also added the bonding driver, that i need for my project (compiling is disabled by default).

If you have a working config please post it. I can also add bonding-driver as module

I just activated the compiling of the bonding driver as module.

To start the bonding, it’s required to load the module, either with modprobe or by adding it to a modules config, e.g. in /etc/modules-load.d/bonding.conf.

Also, the command echo +bond0 > /sys/class/net/bonding_masters must be executed to create the bonding device bond0.

I mean the complete configuration with definition of bonding ports.

Btw. In gcc-bug-report a bisect is requested. Can you try this?


I’m following the steps you in order to create the image, i’m using virtual box with ubuntu 16.04, and gcc --version: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609, but i’ve got some problems at step2:

I tried this: sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-7 50 and i’ve got this message: update-alternatives: error: alternative path /usr/bin/arm-linux-gnueabihf-gcc-7 does not exist

then I tried update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-5 100 and that is OK

but when I try the next code: update-alternatives --config arm-linux-gnueabihf-gcc I’ve got the problem:

There is only one alternative in the group of links arm-linux-gnueabihf-gcc (provee /usr/bin/arm-linux-gnueabihf-gcc): /usr/bin/arm-linux-gnueabihf-gcc-5

Nothing to configure.

Could you help me please?

You need to install gcc7 before defining it as alternative.

You need crosscompiler only if you want to build own kernel/uboot. For image creation you do not need this

Thanks for your response Frank,

I’m new with linux, I already installed gcc-7 with this: sudo add-apt-repository ppa:ubuntu-toolchain-r/test then sudo add-apt-repository ppa:ubuntu-toolchain-r/test then sudo apt-get install gcc-7 g+±7 after that I’ve checked the version gcc-7 --version and it shows gcc-7 (Ubuntu 7.4.0-1ubuntu1~16.04~ppa1) 7.4.0 but when I look for it at /usr/bin/ there is not arm-linux-gnueabihf-gcc-7, hence when I repeat the steps before I get the same problem. Could you please give me and idea? what i’m doing wrong?


you installed gcc7 and not the gcc7-crosscompiler for arm(hf)

my ubuntu 18.4 workstation contains the following packages (for armhf)


i wonder where you read about changing the crosscompiler…imho you need not to do this…this was needed till the point where were problems with gcc7, but these should be fixed…so just install the meta-package gcc-arm-linux-gnueabihf and run build.sh

ok, this instructions are not from me and using official 4.14 repo…

for compiling kernel just use my repo:

and follow instructions in Readme there…you can compile with gcc 7 and you have an actual kernel (4.14.103 or maybe 4.19.25)

I am confused with these 4 lines of command R2-Head0k seems like zeros for 1M but what about the head1-512b?

Next the preloader is loaded onthe same boot partition from block 2 and then the Uboot is loaded.

But when I flashed the ubuntu image I didnt see the uboot in its boot partition.

What I am using for the Khadas Vim device is below commands

#partition with boot and root
        parted -s $LDEV mklabel msdos 1> /dev/null 2>&1
        #parted -s $LDEV mkpart primary fat32 0% 100M 1> /dev/null 2>&1
        parted -s $LDEV mkpart primary fat16 4M 128M 1> /dev/null 2>&1
        START=`cat /sys/block/$DEV/${DEV}p1/start`
        SIZE=`cat /sys/block/$DEV/${DEV}p1/size`
        END_SECTOR=$(expr $START + $SIZE)
        parted -s $LDEV mkpart primary ext4 "${END_SECTOR}s" 100% 1> /dev/null 2>&1
        partprobe $LDEV 1> /dev/null 2>&1
        mkfs.vfat "${LDEV}p1" -n BOOT 1> /dev/null 2>&1
        mkfs.ext4 -O ^metadata_csum,^64bit ${LDEV}p2 -L ROOTFS 1> /dev/null 2>&1
    #copy rootfs contents over to the FS
        mkdir -p $TMPDIR/root
        mkdir -p $TMPDIR/boot
        mount ${LDEV}p1 $TMPDIR/boot
        mount ${LDEV}p2 $TMPDIR/root
        cp -ra $ROOTFS_IMG/rootfs_$ARCH/* $TMPDIR/root/
        mv $TMPDIR/root/boot/* $TMPDIR/boot

    #clean up
        umount $TMPDIR/root
        umount $TMPDIR/boot
        losetup -d $LDEV 1> /dev/null 2>&1
        rm -r $TMPDIR/root $TMPDIR/boot
        partprobe $LDEV 1> /dev/null 2>&1

And if any device which needs a uboot with header and first block to be clear then We use the following.

#Clear first 8mb
        dd if=/dev/zero of=${LDEV} bs=1M count=8 1> /dev/null 2>&1
dd if=$TMPDIR/boot/u-boot.bin.sd.bin of=${LDEV} bs=1 count=444 1> /dev/null 2>&1
        dd if=$TMPDIR/boot/u-boot.bin.sd.bin of=${LDEV} bs=512 skip=1 seek=1 1> /dev/null 2>&1

@frank-w You advice will be helpful


1 Like
BPI-R2-HEAD440-0k.img.gz is 65 bytes
BPI-R2-HEAD1-512b.img.gz is 82 bytes


how do you get the information about 1M?

why do you want to clear the first 8M? you can also simply write new uboot over the old like my uboot/build.sh does

at offset 1M starts user-data-area where my uboot saves uboots environment (8k)

see partition-picture https://wiki.fw-web.de/doku.php?id=en/bpi-r2/storage

so you need only to clear first 1M for clearing boot-data and the following 8k to erase environment, remember that at the end of the first 512 byte your partitiontable is saved…so its better to clear beginning on 512byte

1 Like

Ok I will follow your instruction mentioned on your wiki page. So using that I understand that i need to dd 4 lines to the boot partition and those will be the following for my pkgbuild.

dd if=$TMPDIR/boot/BPI-R2-HEAD440-0k.img of=${LDEV} bs=1024 seek=0 

dd if=$TMPDIR/boot/BPI-R2-HEAD1-512b.img of=${LDEV} bs=512 seek=1

dd if=$TMPDIR/boot/BPI-R2-preloader-DDR1600-20190722-2k.img of=${LDEV} bs=1k seek=2

dd if=$TMPDIR/boot/u-boot.bin of=${LDEV} bs=1k seek=320

I hope this will work. I will copy these files in the boot directory of rootfs from where they will be dd’ed to the boot partition when the pkgbuild is run.

Next I will also use the uEnv.txt to be copied to the boot partition from the boot directory when i build the kernel and move the kernel img as uImage to boot partition. Is this second part of uEnv.txt and uImage correct? From what I have observed from the existing ubuntu img.

Third rootfs will be generated from manjaro linux along with the kernel from your branch.

please do not copy any files to /boot in rootfs because it is the mountpoint for boot-partition and boot will fail if it is not empty. where do you call pkgbuild?

if you do not change filename of kernel (leave uImage and replace the old) you do not need to create a uEnv.txt, only if the name changes or you want to change/extend other vars in the environment. uEnv.txt/uImage needs to be located in the folder you’ve seen above. if you add a new uImage without replacing the old, say uImage_5.3 you create a uEnv.txt and add this at the end (if it exists or you copy an existing file):


btw. instead of copying the 4 files you can simply copy the first 1M from my image to yours…re-read partition table, create filesystems and add kernel+rootfs+modules

Yes boot directory in rootfs will be empty as it is cleaned after using its files What I used to do is compile kernel along with files needed for boot partition using pkgbuild and then build the whole manjaro linux using manjaro-arm-tool official tool this gives us manjaro img to be flashed on media for booting.

No will go with the standard practice of using uImage and will not be changing the name instead will compile kernel separately for every build.

Yes this I can use for testing if the first method fails but to maintain the device with updates I think the first method is stable. Is that correct?

as the 3 headers (and in your case uboot too) do not change, you can simple use the 1MB-DD from my image…as i said you still can update uboot by overwriting the old one…had no problems with this method and i did it many many times :slight_smile:

now i load uboot for testing via tftp to protect my card :smiley:

I can just DD 1M from you image, you means this one?

dd if=/dev/zero of=…/bpi-r2-buster.img bs=1M count=7168

For this I have to always keep a copy of 7GB img :frowning: But Both method will work right ? Either DD 3 imgs or 1MB of your buster img

Also not able to find u-boot.bin ready file anywhere.

This makes the img-file empty

dd if=…/bpi-r2-buster.img bs=1M count=1 of=bpi-r2-bootsect.img

And then write this created images to your sd/img at position 0 (without bs,count,seek,skip)

1 Like

Thanks for this guidance. But why do you suggest to use 7GB img against small multiple imgs? also Is there latest u-boot.bin file pre-compiled? Just to test once this approach works fine then will built it from scratch.

I think you have it already downloaded :smiley: and also if you have uboot inside

Imho i have some on my gdrive…but don’t know how old