Difference between revisions of "Ox64"

From PINE64
Jump to navigation Jump to search
 
(42 intermediate revisions by 5 users not shown)
Line 157: Line 157:
* Some UART adapters based on the FT232H (note that the FT232RL does not work, and neither does the Pine 64 JTAG)
* Some UART adapters based on the FT232H (note that the FT232RL does not work, and neither does the Pine 64 JTAG)
* Some CH340G based adapters work and some don't.
* Some CH340G based adapters work and some don't.
* Flipper Zero UART-Bridge works with baud rate set to 230400.


== Resources and Articles ==
== Resources and Articles ==
Line 186: Line 187:
* [https://twitter.com/thanos_engine/status/1585153938092761093 Phone Concept for BL808]
* [https://twitter.com/thanos_engine/status/1585153938092761093 Phone Concept for BL808]


== Build==
== Building ==
Start the building process cloning both the upstream Buildroot repository and the Buildroot Bouffalo overlay repository:


Open the terminal and create a new directory for the build:
$ mkdir -p ~/ox64
<pre>
$ cd ~/ox64
mkdir buildroot_bouffalo && cd buildroot_bouffalo
$ git clone https://github.com/buildroot/buildroot
</pre>
$ git clone https://github.com/openbouffalo/buildroot_bouffalo


Clone the primary Buildroot repository and the specific Buildroot Bouffalo repository:
Define an environment variable for the Buildroot Bouffalo overlay path:
<pre>
git clone https://github.com/buildroot/buildroot
git clone https://github.com/openbouffalo/buildroot_bouffalo
</pre>


Define an environment variable for the Buildroot Bouffalo overlay path:
$ export BR_BOUFFALO_OVERLAY_PATH=$(pwd)/buildroot_bouffalo
<pre>
export BR_BOUFFALO_OVERLAY_PATH=$(pwd)/buildroot_bouffalo
</pre>


Change directory into the cloned Buildroot folder:
Change directory into the cloned Buildroot folder:
<pre>
 
cd buildroot
$ cd ~/ox64/buildroot
</pre>


Apply the default configuration for Pine64 Ox64:
Apply the default configuration for Pine64 Ox64:
<pre>
make BR2_EXTERNAL=$BR_BOUFFALO_OVERLAY_PATH pine64_ox64_defconfig
</pre>


Use the <code>menuconfig</code> tool to adjust build settings:
$ make BR2_EXTERNAL=$BR_BOUFFALO_OVERLAY_PATH pine64_ox64_defconfig
<pre>
 
make menuconfig
Use the `menuconfig` tool to adjust the build settings:
</pre>
 
[[File:target ABI setting.png|thumb|right|200px|target ABI setting]]
$ make menuconfig
[[File:toolchain setting.png|thumb|right|200px|toolchain setting]]
 
'''Note''': Within <code>menuconfig</code>:
Within `menuconfig`, configure the following:
* Navigate to <code>Target Architecture</code>
 
* Enable <code>Integer Multiplication and Division (M)</code>
* Select `Target Options`
* Enable <code>Atomic Instructions (A)</code>
* Enable `Integer Multiplication and Division (M)`
* Enable <code>Single-precision Floating-point (F)</code>
* Enable `Atomic Instructions (A)` using space key
* Enable <code>Double-precision Floating-point (D)</code>
* Enable `Single-precision Floating-point (F)`
* Set <code>Target ABI</code> to <code>lp64d</code>
* Enable `Double-precision Floating-point (D)`
* Under <code>Toolchain</code>, enable <code>Fortran support</code> and <code>OpenMP support</code>
* Select `Target ABI`, set it to `lp64d` and `press Exit`
* Select `Toolchain`, enable `Fortran support`, enable `OpenMP support`, and Save & Exit


Initiate the build process:
Initiate the build process, but first make sure that your `PATH` variable contains no spaces. For Arch Linux distrubution you may also need to install extra-packages with `sudo pacman -S cpio rsync bc`.
<pre>
make
</pre>
'''Note''': Before executing the <code>make</code> command, ensure your <code>PATH</code> variable doesn't have spaces.


You will get the flashing files into the "/output/images/" directory
$ make


Buildroot will output the needed files to the `~/ox64/buildroot/output/images` directory in about 1 hour, according to your computer processing resources and internet connection speed.


== Flashing ==
This page explains how to flash an Ox64 board and a microSD card to boot the system. You will need a Linux computer, a serial UART adapter, the Ox64 board, and a microSD card.


== Flashing Ox64 SBC and microSD Card ==
=== Prepare images for flashing ===
This section explains how to flash an Ox64 board and a microSD card to boot the system. The required skill levels are fit even for newbies.


=== Prepare the Environment ===
Download the Ox64 images from the latest OpenBouffalo release. You may skip this step if you built your own images as per the instructions in the link:/documentation/Ox64/Software/Building/[Building] page.
You need a Linux machine, a Raspberry Pi Pico to act as a UART adapter, the Ox64 board, and a microSD card.


Start a terminal session and set the working directory to download some files
$ mkdir -p ~/ox64/openbouffalo
$ cd ~/ox64/openbouffalo
$ wget https://github.com/openbouffalo/buildroot_bouffalo/releases/download/v1.0.1/bl808-linux-pine64_ox64_full_defconfig.tar.gz
$ tar -xvzf bl808-linux-pine64_ox64_full_defconfig.tar.gz
$ cd ~/ox64/openbouffalo/firmware
$ xz -v -d -k sdcard-pine64_ox64_full_defconfig.img.xz
$ mv sdcard-pine64_ox64_full_defconfig.img sdcard.img


cd ~/Downloads
==== Optional: create a combined SoC image ====
mkdir ox64 ox64/pico
cd ~/Downloads/ox64/pico
wget https://github.com/Kris-Sekula/Pine64_Ox64_SBC/blob/main/uart/picoprobe.uf2


cd ~/Downloads/ox64
Use the following commands to combine _m0_lowload_bl808_m0.bin_, _d0_lowload_bl808_d0.bin_, and _bl808-firmware.bin_ into a single image. This is mainly useful for troubleshooting (e. g. when using DevCube v1.8.4 or later).
mkdir ox64/devcube183
cd ~/Downloads/ox64/devcube183


Get the DevCube 1.8.3 flasher from one of mirrored servers, verify the hashes listed below, and decompress it:
$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
  # or
$ cd ~/ox64/buildroot/output/images # if you built your own images


* https://openbouffalo.org/static-assets/bldevcube/BouffaloLabDevCube-v1.8.3.zip
$ fallocate -l 0x800000 bl808-combined.bin
* https://hachyderm.io/@mkroman/110787218805897192 > https://pub.rwx.im/~mk/bouffalolab/BouffaloLabDevCube-v1.8.3.zip
$ dd conv=notrunc if=m0_lowload_bl808_m0.bin of=bl808-combined.bin
* https://we.tl/t-eJWShQJ4iF
$ dd conv=notrunc if=d0_lowload_bl808_d0.bin of=bl808-combined.bin seek=$((0x100000))B
* https://cdn.discordapp.com/attachments/771032441971802142/1145565853962735639/BouffaloLabDevCube-v1.8.3.zip
$ cat bl808-firmware.bin >> bl808-combined.bin
 
==== Check that you have the required files for flashing ====


* SHA1: <code>0f2619e87d946f936f63ae97b0efd674357b1166</code>
$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
* SHA256: <code>e6e6db316359da40d29971a1889d41c9e97d5b1ff1a8636e9e6960b6ff960913</code>
  # or
$ cd ~/ox64/buildroot/output/images # if you built your own images


  wget https://openbouffalo.org/static-assets/bldevcube/BouffaloLabDevCube-v1.8.3.zip
  $ ls -1 *808*.bin *.img
unzip BouffaloLabDevCube-v1.8.3.zip
chmod u+x BLDevCube-ubuntu


Download compressed file from https://github.com/openbouffalo/buildroot_bouffalo/releases/ and decompress it.
Expected files:


(You can also get the compressed the file from https://github.com/openbouffalo/buildroot_bouffalo/releases/download/v1.0.1/bl808-linux-pine64_ox64_full_defconfig.tar.gz)
* `bl808-combined.bin` -- If you created the combined image.
* `bl808-firmware.bin` -- OpenSBI and UBoot DTB files. Runs on the D0 core.
* `d0_lowload_bl808_d0.bin` -- Startup code for the D0 core.
* `m0_lowload_bl808_m0.bin` -- Startup code for the M0 core.
* `sdcard.img` -- Kernel and root filesystem. Runs on the D0 core.


cd ~/Downloads/ox64
=== Set up your UART adapter ===
mkdir openbouffalo && cd openbouffalo
wget https://github.com/openbouffalo/buildroot_bouffalo/releases/download/v1.0.1/bl808-linux-pine64_ox64_full_defconfig.tar.gz
tar -xvzf bl808-linux-pine64_ox64_full_defconfig.tar.gz
mv bl808-linux-pine64_ox64_full_defconfig.img sdcard.img


You'll get the following file:
In this section we will configure and wire up a UART adapter in order to flash the Ox64. Choose one of the options below based on the hardware available to you; the first two are the most convenient since they minimise the number of times you will need to swap electrical connections.
  m0_lowload_bl808_m0.bin
  bl808-firmware.bin
  d0_lowload_bl808_d0.bin
  sdcard.img


==== Option 1: Raspberry Pi Pico ====


=== Establish Serial Communication from PC to Ox64 using Pi Pico ===
First, download the Raspberry Pi Pico firmware that allows it to act as a serial UART adapter:
Open a terminal and check the connected USB serial devices:


  ls /dev/ttyACM*
  $ mkdir -p ~/ox64/pico
$ cd ~/ox64/pico
$ wget https://github.com/Kris-Sekula/Pine64_Ox64_SBC/raw/main/uart/picoprobe.uf2


Set the Raspberry Pi Pico board into programming mode:
Put the Raspberry Pi Pico board into programming mode:


* Press the BootSel button
* Press the BootSel button
Line 299: Line 289:
* Release the BootSel button
* Release the BootSel button


''Note: you could also ground pin28 to TP6 while powering.''
NOTE: As an alternative to pressing the BootSel button, you can also connect the probe point `TP6` (located on the bottom of the Pico board) to any ground point (e. g. pin 28).
 
The Pico will now appear as a USB mass storage device. Copy the `UF2` file to program it:
 
$ cp ~/ox64/pico/picoprobe.uf2 /media/<user>/RPI-RP2
 
Next, connect the Ox64 board to the Pico according to the following wiring diagram:
 
[cols="1,1,1"]
|===
| Ox64 | PI PICO | /dev/tty
 
| uart0_Tx_GPIO14_pin1
| uart0_Rx_pin17
| ACM1 for flashing
 
| uart0_Rx_GPIO15_pin2
| uart0_Tx_pin16
| ACM1 for flashing
 
| Rxd_GPIO17_pin31
| uart1_Tx_pin6
| ACM0 for serial console
 
| Txd_GPIO16_pin32
| uart1_Rx_pin7
| ACM0 for serial console
 
| gnd_pin38
| gnd_pin38/3
|
 
| vbus5v_pin40
| vbus5v_pin40
|
|===
 
With the Pico flashed and wired as per the instructions above, we have access to two of the Ox64's UART ports at the same time. This configuration eliminates the need to switch the physical connections for flashing or testing the system.
 
Reconnect the Pico to your computer's USB port and verify that we have access to all the serial ports we need:
 
$ ls /dev/ttyACM*
 
Expected result:
 
* `/dev/ttyACM0` connects to the D0 core's (i.e. Linux's) serial console
* `/dev/ttyACM1` is used for flashing (but also connects to the M0 core's serial console)
 
==== Option 2: STM32 Bluepill ====
 
The Bluepill is an affordable STM32 development board, based on the STM32F103C8T6 chip. We can program it to act as a USB serial adapter, just like we did with the Raspberry Pi Pico.
 
[NOTE]
 
The one catch is that you already need a serial adapter in order to program your Bluepill board. The good news is that you serial adapter does **not** have to be one from from the link:/documentation/Ox64/Further_information/Compatible_UARTs/[Compatible UARTs] list. These programming instructions have been tested with a FT232RL adapter (which, notably, is listed as _not_ supported on that list).
 
If you own an SWD-capable debugger (ST-Link, J-link, etc.) you can use that for programming the Bluepill as well, although instead of `stm32flash` console command you would be using https://openocd.org/[openocd] or other suitable software.
 
WARNING: Your serial adapter must use 3.3V logic levels.
 
Install software to flash Bluepill. For Debian-based systems just install package from repository:
 
$ sudo apt install stm32flash
 
For Arch Linux systems, use the AUR repository:
 
$ mkdir -p ~/ox64/bluepill
$ cd ~/ox64/bluepill
$ git clone https://aur.archlinux.org/stm32flash.git
$ cd ~/ox64/bluepill/stm32flash
$ makepkg -si
 
Download the https://github.com/r2axz/bluepill-serial-monster[Bluepill Serial Monster] firmware:
 
$ mkdir -p ~/ox64/bluepill
$ cd ~/ox64/bluepill
$ wget https://github.com/r2axz/bluepill-serial-monster/releases/download/v2.6.4/bluepill-serial-monster.hex
 
Put the Bluepill into programming mode:
 
* Set boot jumpers for booting from rom: Boot0=1, Boot1=0.
* Connect it to a USB-Serial adapter with A9 to Rx, A10 to Tx, GND to GND, 3v3 to Vcc.
* Apply power by plugging the USB cable to PC. Press the Reset button.
 
Find your USB serial adapter's device path with `ls /dev/ttyUSB* /dev/ttyACM*` (or similar); for the rest of this section we will refer to it as `/dev/tty[DEVICE]`. Upload the firmware:
 
$ cd ~/ox64/bluepill
$ sudo stm32flash -w bluepill-serial-monster.hex /dev/tty[DEVICE]
After upload, set boot jumpers for boot from flash: Boot0=0, Boot1=0. Disconnect the USB serial adapter from both the PC and Bluepill board.
 
Next, connect the Ox64 board to the Bluepill according to the following wiring diagram:
 
[cols="1,1,1"]
|===
| Ox64 | Bluepill | /dev/tty
 
| uart0_Tx_GPIO14_pin1
| uart0_Rx_A3
| ACM1 for flashing
 
| uart0_Rx_GPIO15_pin2
| uart0_Tx_A2
| ACM1 for flashing
 
| Rxd_GPIO17_pin31
| uart1_Tx_A9
| ACM0 for serial console
 
| Txd_GPIO16_pin32
| uart1_Rx_A10
| ACM0 for serial console
 
| gnd_pin38
| GND
|
 
| vbus5v_pin40
| 5V
|


Copy <code>picoprobe.uf2</code> file into the new device <code>/media/<user>/RPI-RP2</code>:
|===


cp ~/Downloads/ox64/pico/picoprobe.uf2 /media/<user>/RPI-RP2
With the Bluepill flashed and wired as per the instructions above, we have access to two of the Ox64's UART connections at the same time. This configuration eliminates the need to switch the physical connections for flashing or testing the system.


After flashing, the device will auto-set in serial UART communication mode according to the following wiring diagram.
Connect the Bluepill to your computer's USB port and verify that we have access to all the serial ports we need:


[[File:Pine Serial v2.png|thumb|right|Wiring Raspberry Pi Pico to Pine64 Ox64 SBC]]
$ ls /dev/ttyACM*


OX64                      PI PICO
Expected result:
uart0_Tx_GPIO14_pin1 <->  uart0_Rx_pin17
uart0_Rx_GPIO15_pin2 <->  uart0_Tx_pin16
Rxd_GPIO17_pin31    <->  uart1_Tx_pin6
Txd_GPIO16_pin32    <->  uart1_Rx_pin7
gnd_pin38            <->  gnd_pin38/3   
vbus5v_pin40        <->  vbus5v_pin40


=== Flash Your Ox64 ===
* `/dev/ttyACM0` connects to the D0 core's (i.e. Linux's) serial console
There are two new ports to choose from, <code>/dev/ttyACM0</code> for serial console and <code>/dev/ttyACM1</code> for DevCube flashing.
* `/dev/ttyACM1` is used for flashing (but also connects to the M0 core's serial console)
* `/dev/ttyACM2` (unused)


minicom -b 2000000 -D /dev/ttyACM0
==== Option 3: Generic UART adapter ====


Set the Ox64 board into programming mode:
image:/documentation/Ox64/images/ox64_pinout.png[Ox64 pinout,title="Ox64 pinout", 300, float="right"]
 
Check that your serial adapter is on the link:/documentation/Ox64/Further_information/Compatible_UARTs/[Compatible UARTs] list. You will (most likely) only have one serial interface available to you; unlike the previous options you will be using this same serial interface for both flashing and testing the system.
 
Find its device path with `ls /dev/ttyUSB* /dev/ttyACM*` (or similar); for the rest of this section we will refer to it as `/dev/tty[DEVICE]`.
 
You will also need a way of powering your Ox64. If your serial adapter has a 5V line, you can connect it to VBUS (pin 40). Otherwise, you can connect either the micro-B or the USB-C port on the Ox64 to any 5V power supply.
 
WARNING: Your serial adapter must use 3.3V logic levels.
 
Refer to the pinout image below. Connect your UART adapter as follows:
 
* RX -> UART0_TX / GPIO14 / pin 1
* TX -> UART0_RX / GPIO15 / pin 2
* GND -> any ground (e. g. pin 3)
 
Proceed with the instructions in the sections that follow, up to and including <<flashing_the_ox64>> and <<flashing_the_microsd_card>>, but replace all occurrences of `/dev/ttyACM1` with `/dev/tty[DEVICE]`.
 
Next, power off the Ox64 and re-connect your UART adapter as follows:
 
* RX -> TXD / GPIO16 / pin 32
* TX -> RXD / GPIO17 / pin 31
* GND -> any ground (e. g. pin 33)
 
Then, follow the instructions in <<booting_for_the_first_time>>, but replace all occurrences of `/dev/ttyACM0` with `/dev/tty[DEVICE]`. You should then have a working Linux system.
 
=== Download flashing tools ===
 
You have a choice of flashing software:
 
* DevCube: GUI-based closed source flashing tool
* CLI (`bflb-iot-tool`): command line open source flashing tool
 
==== DevCube installation ====
 
Download the latest DevCube flashing tool from BouffaloLab's website:
 
$ mkdir -p ~/ox64/devcube
$ cd ~/ox64/devcube
$ wget https://dev.bouffalolab.com/media/upload/download/BouffaloLabDevCube-v1.8.9.zip
$ unzip BouffaloLabDevCube-v1.8.9.zip
$ chmod u+x BLDevCube-ubuntu
 
If you did not create a link:#optional_create_a_combined_soc_image[combined image] you may need an older version of the DevCube. In that case, download v1.8.3 from one of the mirrors below:
 
* https://openbouffalo.org/static-assets/bldevcube/BouffaloLabDevCube-v1.8.3.zip
* https://hachyderm.io/@mkroman/110787218805897192[] > https://pub.rwx.im/~mk/bouffalolab/BouffaloLabDevCube-v1.8.3.zip
* https://we.tl/t-eJWShQJ4iF
* https://cdn.discordapp.com/attachments/771032441971802142/1145565853962735639/BouffaloLabDevCube-v1.8.3.zip
 
Verify that your copy of `BouffaloLabDevCube-v1.8.3.zip` matches the hashes below:
 
* SHA1: `0f2619e87d946f936f63ae97b0efd674357b1166`
* SHA256: `e6e6db316359da40d29971a1889d41c9e97d5b1ff1a8636e9e6960b6ff960913`
 
==== CLI packages installation ====
 
Install `bflb-iot-tool` using your preferred method of managing PIP packages. One option is to set up a Python virtual environment as follows:
 
$ sudo apt install pipenv # for Debian-based systems
  # or
$ sudo pacman -S python-pipenv # for Arch Linux systems
 
$ cd ~/ox64/
$ pipenv install setuptools # install prerequisite of CLI flash tool
$ pipenv install bflb-iot-tool # install CLI flash tool
$ pipenv shell # activate virtual environment
$ # bflb-iot-tool --help # return info about the tool
 
 
NOTE: Each time you open a new terminal window you will need to `cd ~/ox64/` and re-run `pipenv shell` to reactivate the virtual environment.
 
=== Flashing the Ox64 ===
 
Put the Ox64 into programming mode:


* Press the BOOT button
* Press the BOOT button
Line 328: Line 506:
* Release the BOOT button
* Release the BOOT button


Close <code>minicom</code>. Open a new terminal window to run the DevCube flasher:
==== CLI flashing method ====


cd ~/Downloads/ox64/devcube183
Set up some environment variables to save typing them out later:
./BLDevCube-ubuntu


Select chip [BL808], press Finish and switch to [MCU] tab
$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
  # or
$ cd ~/ox64/buildroot/output/images # if you built your own images


  M0 Group[group0] Image Addr [0x58000000] [PATH to m0_lowload_bl808_m0.bin]
  $ PORT=/dev/ttyACM1
D0 Group[group0] Image Addr [0x58100000] [PATH to d0_lowload_bl808_d0.bin]
  $ BAUD=230400  # safe value for macOS, set to 2000000 for faster flashing on Linux
Interface: UART
Port/SN: /dev/ttyACM1 (make sure you don't use /dev/ttyACM0, it's used by the minicom console)
  Uart rate 2000000
UART TX is physical pin 1/GPIO 14.
UART RX is physical pin 2/GPIO 15.
Click 'Create & Download' and wait until it's done


Switch to [IOT] tab:
Finally, flash the Ox64. If you created a link:#optional_create_a_combined_soc_image[combined image] then run the command below:


  Enable 'Single Download', set Address with 0x800000, choose [PATH to bl808-firmware.bin]
  $ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x0 --firmware bl808-combined.bin --single
Port/SN: /dev/ttyACM1 (make sure you don't use ACM0, it's used by minicom console)
Click 'Create & Download' again and wait until it's done
Close DevCube


==== Open-Source Flashing Using CLI ====
Otherwise, run the following commands:
For those who do not want to use the DevCube, BouffaloLab provides open-source flashing packages <code>bflb-iot-tool</code> and <code>bflb-mcu-tool</code>.


''Note: While these packages do contain binaries in addition to the Python source code, those binaries do not appear to be used for UART flashing.''
$ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x0 --firmware m0_lowload_bl808_m0.bin --single
$ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x100000 --firmware d0_lowload_bl808_d0.bin --single
$ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x800000 --firmware bl808-firmware.bin --single


First, install <code>bflb-iot-tool</code> using your preferred method of managing PIP packages.  
If you get permission errors when running any of the commands above, run `ls -l /dev/tty[DEVICE]`, to find out which group is allowed to talk to serial ports and add your user to that group, with `sudo usermod -a -G [GROUP] $USER` (i.e. `dialout` for Debian or `uucp` for Arch Linux). Make sure you re-login. Running the commands as `root` is not recommended since this will make `bflb-iot-tool` create root-owned files in your home directory. You can now run `exit` from virtual environment.


sudo pip install bflb-iot-tool --break-system-packages # we are *not* using bflb-mcu-tool
==== BLDevCube flashing method ====


One option is to set up a Python virtual environment:
Open a new terminal window to run the DevCube flasher:
sudo apt install virtualenv python3-virtualenv
python3 -m venv ~/ox64_venv
. ~/ox64_venv/bin/activate
pip install bflb-iot-tool # we are *not* using bflb-mcu-tool
Note that each time you open a new terminal window you will need to re-run the second command above to reactivate the virtual environment.


Next, put Ox64 in pragramming mode (press button, while power on) and execute the following commands to flash the BL808.
$ cd ~/ox64/devcube
$ ./BLDevCube-ubuntu
 
Select chip [BL808], press Finish, and configure BOTH the [MCU] and [IOT] tabs as follows. When you switch between tabs double check that they still match the settings below:
 
[cols="~,~"]
|===
|Interface
|UART
 
|Port/SN
|`/dev/ttyACM1`
 
|UART rate
|230400 (safe value for macOS, set to 2000000 for faster flashing on Linux)
|===
 
If you created a link:#optional_create_a_combined_soc_image[combined image] then you only need to use the [IOT] tab:
 
* Enable 'Single Download'
* Image Address [0x0], [PATH to bl808-combined.bin]
* Click 'Create & Download' and wait until it's done
* Close DevCube
 
Otherwise, start in the [MCU] tab:
 
* M0 Group[group0], Image Address [0x58000000], [PATH to m0_lowload_bl808_m0.bin]
* D0 Group[group0], Image Address [0x58100000], [PATH to d0_lowload_bl808_d0.bin]
* Click 'Create & Download' and wait until it's done
 
Then, switch to the [IOT] tab:
 
* Enable 'Single Download'
* Image Address [0x800000], [PATH to bl808-firmware.bin]
* Click 'Create & Download' again and wait until it's done
* Close DevCube
 
=== Erasing the microSD card ===
 
Make sure there are no signatures or partitions left, and overwrite the first sectors with zeroes. You can find the target device under `lsblk` command.
 
$ sudo wipefs /dev/[DEVICE]
$ sudo wipefs --all --force /dev/[DEVICE]*
$ sudo dd if=/dev/zero of=/dev/[DEVICE] status=progress bs=32768 count=1
 
Optionally you can zeroes the whole device:
 
$ sudo dd if=/dev/zero of=/dev/[DEVICE] status=progress bs=32768 count=$(expr $(lsblk -bno SIZE /dev/[DEVICE] | head -1) \/ 32768)
 
=== Flashing the microSD card ===
 
Insert the microSD card into your PC, locate its device under `lsblk` and write the image:
 
$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
  # or
$ cd ~/ox64/buildroot/output/images # if you built your own images
 
$ sudo dd if=sdcard.img of=/dev/[DEVICE] bs=1M status=progress conv=fsync
 
=== Booting for the first time ===
 
Power off your Ox64 and insert the microSD card.
 
Open a terminal window to connect to the D0 core’s (i.e. Linux’s) serial console:
 
$ minicom -b 2000000 -D /dev/ttyACM0
 
If you are using a Pico or Bluepill as your serial adapter, open another terminal window to to monitor the M0 core’s serial console (reminder: `/dev/ttyACM1` is the same port we previously used for flashing):
 
$ minicom -b 2000000 -D /dev/ttyACM1
 
Re-apply power to the Ox64.
 
On the main/D0 console (`/dev/ttyACM0`) you will see Linux booting up. When prompted, log in as `root` with no password. In case the SD card is missing or empty, you'll get a `Card did not respond to voltage select! : -110` error.
 
On the M0 console (`/dev/ttyACM1`) you'll see following messages until the sytem is fully loaded:
 
----
[I][MBOX] Mailbox IRQ Stats:
[I][MBOX] Peripheral SDH (33): 0
[I][MBOX] Peripheral GPIO (60): 0
[I][MBOX] Unhandled Interupts: 0 Unhandled Signals 0
----
 
Once the system is running, the "MBOX" logs will abruptly disappear and you'll be able to manage the M0 multimedia core, i.e. wifi settings, etc. When prompted, type `help` to see available commands.
 
==== Connecting the Ox64 to your WiFi network ====
 
The simplest way to connect is to run the following command from the Linux console (i.e. `/dev/ttyACM0`):
 
$ blctl connect_ap <YourSSID> <YourPassword>
 
Wait for it to connect (if you're monitoring the M0 console on `/dev/ttyACM1` it should tell you when it's done), then run the following command from the Linux console:
 
$ udhcpc -i bleth0
Unfortunately the WiFi range leaves something to be desired. When you are performing the procedure above for the first time, move the Ox64 right next to your router. Once you are successfully connected, you can try experimenting with the maximum range.


PORT=/dev/ttyACM1 # this will depend on which serial adapter you use
For more information on using the `blctl` command, see https://github.com/bouffalolab/blwnet_xram[here].
BAUD=115200 # safe value for macOS, if using Linux set to 2000000 for faster flashing
cd ~/Downloads/ox64/buildroot_bouffalo/buildroot/output/images
bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x000000 --firmware m0_lowload_bl808_m0.bin --single
bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x100000 --firmware d0_lowload_bl808_d0.bin --single
bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x800000 --firmware bl808-firmware.bin --single


If you get permission errors from these CLI commands, you may need to add your user to the <code>dialout</code> group. Running the commands as <code>root</code> is not recommended since this will make <code>bflb-iot-tool</code> create <code>root</code>-owned files in your home directory.
=== Appendix ===


==== Adding Nuttx RTOS ====


==== BL808 Address Details ====
In this section, we will set up our Ox64 to dual-boot both Linux and the NuttX real-time operating system. For more information see the https://nuttx.apache.org/docs/latest/platforms/risc-v/bl808/boards/ox64/index.html[official documentation].


Note that addresses are different according the flashing method: DevCube or CLI.
First, write the normal Linux image to the SD card if you have not done so already. You can find the correct device under `lsblk`:


DevCube for M0 set address = 0x58000000
$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
DevCube for D0 set address = 0x58100000
  # or
DevCube for LP set address = 0x58200000
$ cd ~/ox64/buildroot/output/images # if you built your own images


CLI for M0 set address = 0x000000
$ sudo dd if=/sdcard.img of=/dev/[DEVICE] bs=1M conv=fsync status=progress
CLI for D0 set address = 0x100000
CLI for LP set address = 0x200000


Run the following command to re-read the partition tables. Re-inserting the SD card works too:


=== Flash Your MicroSD Card ===
$ sudo blockdev --rereadpt /dev/[DEVICE]
Insert microSD card into PC, locate its device file (<code>/dev/sdb</code>, for example), erase the start of the card and proceed to flashing.


cd ~/Downloads/ox64/buildroot_bouffalo/buildroot/output/images
Download the NuttX image:
# xz -v -d -k sdcard-pine64_ox64_full_defconfig.img.xz
sudo dd if=/dev/zero of=/dev/sdb count=1 bs=32768
sudo dd if=sdcard.img of=/dev/sdb bs=1M status=progress conv=fsync


=== First Booting ===
$ mkdir -p ~/ox64/nuttx
Insert microSD card into Ox64 and set a UART connection to the Ox64 board.
$ cd ~/ox64/nuttx
$ wget -O ImageNuttx https://github.com/lupyuen2/wip-pinephone-nuttx/releases/download/bl808d-1/Image


* Serial console access:
Mount the boot partition and make the required modifications:
* UART TX is physical pin 32/GPIO 16.
* UART RX is physical pin 31/GPIO 17.
* Baud 2000000.


Choose from serial devices <code>/dev/ttyACM0</code> and <code>/dev/ttyACM1</code>, using the lower number.
$ sudo mount /dev/[DEVICE]2 /mnt
$ sudo cp ImageNuttx /mnt/
$ sudo tee -a /mnt/extlinux/extlinux.conf <<EOF
LABEL PINE64 OX64 Nuttx
        KERNEL ../ImageNuttx
        FDT ../bl808-pine64-ox64.dtb
EOF
$ sudo umount /mnt


minicom -b 2000000 -D /dev/ttyACM0
Mount the rootfs and make the required modifications:


Re-apply power to the Ox64 and enjoy the booting!
$ sudo mount /dev/[DEVICE]3 /mnt
$ sudo cp ImageNuttx /mnt/boot/
$ sudo tee -a /mnt/boot/extlinux/extlinux.conf <<EOF
LABEL PINE64 OX64 Nuttx
        KERNEL ../ImageNuttx
        FDT ../bl808-pine64-ox64.dtb
EOF
$ sudo umount /mnt


[[Category:Ox64]]
Enjoy your new Nuttx booting option!
[[Category:Bouffalo BL808]]

Latest revision as of 13:38, 19 August 2024

The Ox64
Pinout of the production version
Powered by RISC-V

The Ox64 is a RISC-V based single-board computer based on the Bouffalo Lab BL808 RISC-V SoC with C906 64-bit and E907/E902 32-bit CPU cores supported by 64 MB of embedded PSRAM memory, and with built-in WiFi, Bluetooh and Zigbee radio interfaces. The Ox64 comes in a breadboard-friendly form-factor, has a microSD card slot, a USB 2.0 Type-C port, and many other peripheral interfaces for makers to integrate with sensors and other devices.

Software Releases

Quick Links to the Source of OS Images Build

There is a community effort to bring updated kernels, peripherals and buildroot - Lots of communication happening in the #ox64-nutcracker channel.

  • buildroot bringing all the work below together with a bootable kernel and updated filesystem images for SD cards
  • U-Boot and OpenSBI work by Smauel
  • Kernel IRQChip, SDCard, and (WIP) USB by arm000, Alexander Horner and others
  • OpenBouffalo Firmware low_load drivers by Fishwaldo and others

Original Linux Images provided by Bouffalo - Very basic alpha build which are only fit for board bring up and testing purposes.

Toolchain:

  • elf_newlib_toolchain/bin/riscv64-unknown-elf-gcc (Xuantie-900 elf newlib gcc Toolchain V2.2.5 B-20220323) 10.2.0
  • linux_toolchain/bin/riscv64-unknown-linux-gnu-gcc (Xuantie-900 linux-5.10.4 glibc gcc Toolchain V2.2.4 B-20211227) 10.2.0
  • cmake version 3.19.3

Software Development Kits

SoC and Memory Specification

Bouffalo Lab icon.png

Based on the Bouffalo Lab BL808

BL808 Block Diagram.jpg

CPU Architecture

T-Head.png

T-Head C906 480 MHz 64-bit RISC-V CPU:

  • Supports RISC-V RV64IMAFCV instruction architecture
  • Five-stage single-issue sequentially executed pipeline
  • Level-1 instruction and data cache of Harvard architecture, with a size of 32 KB and a cache line of 64B
  • Sv39 memory management unit, realizing the conversion of virtual and real addresses and memory management
  • jTLB that supports 128 entries
  • Supports AXI 4.0 128-bit master interface
  • Supports core local interrupt (CLINT) and platform-level interrupt controller (PLIC)
  • With 80 external interrupt sources, 3 bits for configuring interrupt priority
  • Supports BHT (8K) and BTB
  • Compatible with RISC-V PMP, 8 configurable areas
  • Supports hardware performance monitor (HPM) units
  • See here

T-Head E907 320 MHz 32-bit RISC-V CPU:

  • Supports RISC-V RV32IMAFCP instruction set
  • Supports RISC-V 32-bit/16-bit mixed instruction set
  • Supports RISC-V machine mode and user mode
  • Thirty-two 32-bit integer general purpose registers (GPR) and thirty-two 32-bit/64-bit floating-point GPRs
  • Integer (5-stage)/floating-point (7-stage), single-issue, sequentially executed pipeline
  • Supports AXI 4.0 main device interface and AHB 5.0 peripheral interface
  • 32K instruction cache, two-way set associative structure
  • 16K data cache, two-way set associative structure
  • See here

T-Head E902 150 MHz 32-bit RISC-V CPU:

System Memory

  • Embedded 64MB PSRAM

Board Features

Network

  • 2.4 GHz 1T1R WiFi 802.11 b/g/n
  • Bluetooth 5.2
  • Zigbee
  • 10/100 Mbit/s Ethernet (optional, on expansion board)

Storage

  • On-board 16 Mbit (2 MB) or 128 Mbit (16 MB) XSPI NOR flash memory
  • MicroSD, supports SDHC and SDXC (only on the 128 Mbit version)

Expansion Ports

  • USB 2.0 OTG port
  • 26 GPIO pins, including SPI, I2C and UART functionality, possible I2S and GMII expansion
  • Dual-lane MiPi CSI port, located at USB-C port, for camera module

Audio

  • Microphone (optional, on the camera module)
  • Speaker (optional, on the camera module)

Board Information, Schematics and Certifications

Pinout for wiring ethernet PHY to EMAC
  • Baseboard dimensions: 51 mm x 21 mm x 19 mm x 3.5 mm (breadboard friendly)
  • Input power: 5 V, 0.5 A through the microUSB or USB-C ports

Production version schematic:

Prototype (dispatched to developers) schematic:

Certifications:

  • Disclaimer: Please note that PINE64 SBC is not a "final" product and in general certification is not necessary.
  • Not yet available

Datasheets for Components and Peripherals

Bouffalo BL808 SoC information:

SPI NOR Flash information:

Power Regulator information:

MicroSD socket information:

Compatible UARTs when in bootloader mode

When the Ox64 is in bootloader mode, some UARTs are unable to communicate with it. When this is the case, utilities such as BLDevCube are unable to actually program the device. If you see "Shake hand fail" and an empty ack, and your device is in bootloader mode, then it is likely an incompatible UART.

The below devices have been tested and verified as working:

  • Raspberry Pi Pico - running the following UART firmware (GP4 and GP5 are used for port 0, GP12 and GP13 for port 1)
  • Compiled binary for Pi Pico and connectivity diagram is here
  • ESP32 with CP210x - bridge the EN pin to ground to disable the ESP32 itself, and then connect the TX on the esp32 to 14 on the Ox64 and RX to pin 15. Note that only baud rate 115200 works, and this doesn't seem to work for everyone)
  • Stand-alone CP2102 dongle works at 115200 baud. Brand used was HiLetgo.
  • STM32F401 BlackPill - running the Black Magic Debug firmware
  • STM32F103C8T6 BluePill - running Black Magic Debug.
  • Some UART adapters based on the FT232H (note that the FT232RL does not work, and neither does the Pine 64 JTAG)
  • Some CH340G based adapters work and some don't.
  • Flipper Zero UART-Bridge works with baud rate set to 230400.

Resources and Articles

Ox64 BL808 RISC-V SBC articles by Lup Yuen LEE:

Git repositories:

Development Efforts

Building

Start the building process cloning both the upstream Buildroot repository and the Buildroot Bouffalo overlay repository:

$ mkdir -p ~/ox64
$ cd ~/ox64
$ git clone https://github.com/buildroot/buildroot
$ git clone https://github.com/openbouffalo/buildroot_bouffalo

Define an environment variable for the Buildroot Bouffalo overlay path:

$ export BR_BOUFFALO_OVERLAY_PATH=$(pwd)/buildroot_bouffalo

Change directory into the cloned Buildroot folder:

$ cd ~/ox64/buildroot

Apply the default configuration for Pine64 Ox64:

$ make BR2_EXTERNAL=$BR_BOUFFALO_OVERLAY_PATH pine64_ox64_defconfig

Use the `menuconfig` tool to adjust the build settings:

$ make menuconfig

Within `menuconfig`, configure the following:

  • Select `Target Options`
  • Enable `Integer Multiplication and Division (M)`
  • Enable `Atomic Instructions (A)` using space key
  • Enable `Single-precision Floating-point (F)`
  • Enable `Double-precision Floating-point (D)`
  • Select `Target ABI`, set it to `lp64d` and `press Exit`
  • Select `Toolchain`, enable `Fortran support`, enable `OpenMP support`, and Save & Exit

Initiate the build process, but first make sure that your `PATH` variable contains no spaces. For Arch Linux distrubution you may also need to install extra-packages with `sudo pacman -S cpio rsync bc`.

$ make

Buildroot will output the needed files to the `~/ox64/buildroot/output/images` directory in about 1 hour, according to your computer processing resources and internet connection speed.

Flashing

This page explains how to flash an Ox64 board and a microSD card to boot the system. You will need a Linux computer, a serial UART adapter, the Ox64 board, and a microSD card.

Prepare images for flashing

Download the Ox64 images from the latest OpenBouffalo release. You may skip this step if you built your own images as per the instructions in the link:/documentation/Ox64/Software/Building/[Building] page.

$ mkdir -p ~/ox64/openbouffalo
$ cd ~/ox64/openbouffalo
$ wget https://github.com/openbouffalo/buildroot_bouffalo/releases/download/v1.0.1/bl808-linux-pine64_ox64_full_defconfig.tar.gz
$ tar -xvzf bl808-linux-pine64_ox64_full_defconfig.tar.gz
$ cd ~/ox64/openbouffalo/firmware
$ xz -v -d -k sdcard-pine64_ox64_full_defconfig.img.xz
$ mv sdcard-pine64_ox64_full_defconfig.img sdcard.img

Optional: create a combined SoC image

Use the following commands to combine _m0_lowload_bl808_m0.bin_, _d0_lowload_bl808_d0.bin_, and _bl808-firmware.bin_ into a single image. This is mainly useful for troubleshooting (e. g. when using DevCube v1.8.4 or later).

$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
 # or
$ cd ~/ox64/buildroot/output/images # if you built your own images
$ fallocate -l 0x800000 bl808-combined.bin
$ dd conv=notrunc if=m0_lowload_bl808_m0.bin of=bl808-combined.bin
$ dd conv=notrunc if=d0_lowload_bl808_d0.bin of=bl808-combined.bin seek=$((0x100000))B
$ cat bl808-firmware.bin >> bl808-combined.bin

Check that you have the required files for flashing

$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
 # or
$ cd ~/ox64/buildroot/output/images # if you built your own images
$ ls -1 *808*.bin *.img

Expected files:

  • `bl808-combined.bin` -- If you created the combined image.
  • `bl808-firmware.bin` -- OpenSBI and UBoot DTB files. Runs on the D0 core.
  • `d0_lowload_bl808_d0.bin` -- Startup code for the D0 core.
  • `m0_lowload_bl808_m0.bin` -- Startup code for the M0 core.
  • `sdcard.img` -- Kernel and root filesystem. Runs on the D0 core.

Set up your UART adapter

In this section we will configure and wire up a UART adapter in order to flash the Ox64. Choose one of the options below based on the hardware available to you; the first two are the most convenient since they minimise the number of times you will need to swap electrical connections.

Option 1: Raspberry Pi Pico

First, download the Raspberry Pi Pico firmware that allows it to act as a serial UART adapter:

$ mkdir -p ~/ox64/pico
$ cd ~/ox64/pico
$ wget https://github.com/Kris-Sekula/Pine64_Ox64_SBC/raw/main/uart/picoprobe.uf2

Put the Raspberry Pi Pico board into programming mode:

  • Press the BootSel button
  • Apply power by plugging the USB cable to PC
  • Release the BootSel button

NOTE: As an alternative to pressing the BootSel button, you can also connect the probe point `TP6` (located on the bottom of the Pico board) to any ground point (e. g. pin 28).

The Pico will now appear as a USB mass storage device. Copy the `UF2` file to program it:

$ cp ~/ox64/pico/picoprobe.uf2 /media/<user>/RPI-RP2

Next, connect the Ox64 board to the Pico according to the following wiring diagram:

[cols="1,1,1"] |=== | Ox64 | PI PICO | /dev/tty

| uart0_Tx_GPIO14_pin1 | uart0_Rx_pin17 | ACM1 for flashing

| uart0_Rx_GPIO15_pin2 | uart0_Tx_pin16 | ACM1 for flashing

| Rxd_GPIO17_pin31 | uart1_Tx_pin6 | ACM0 for serial console

| Txd_GPIO16_pin32 | uart1_Rx_pin7 | ACM0 for serial console

| gnd_pin38 | gnd_pin38/3 |

| vbus5v_pin40 | vbus5v_pin40 | |===

With the Pico flashed and wired as per the instructions above, we have access to two of the Ox64's UART ports at the same time. This configuration eliminates the need to switch the physical connections for flashing or testing the system.

Reconnect the Pico to your computer's USB port and verify that we have access to all the serial ports we need:

$ ls /dev/ttyACM*

Expected result:

  • `/dev/ttyACM0` connects to the D0 core's (i.e. Linux's) serial console
  • `/dev/ttyACM1` is used for flashing (but also connects to the M0 core's serial console)

Option 2: STM32 Bluepill

The Bluepill is an affordable STM32 development board, based on the STM32F103C8T6 chip. We can program it to act as a USB serial adapter, just like we did with the Raspberry Pi Pico.

[NOTE]

The one catch is that you already need a serial adapter in order to program your Bluepill board. The good news is that you serial adapter does **not** have to be one from from the link:/documentation/Ox64/Further_information/Compatible_UARTs/[Compatible UARTs] list. These programming instructions have been tested with a FT232RL adapter (which, notably, is listed as _not_ supported on that list).

If you own an SWD-capable debugger (ST-Link, J-link, etc.) you can use that for programming the Bluepill as well, although instead of `stm32flash` console command you would be using https://openocd.org/[openocd] or other suitable software.

WARNING: Your serial adapter must use 3.3V logic levels.

Install software to flash Bluepill. For Debian-based systems just install package from repository:

$ sudo apt install stm32flash

For Arch Linux systems, use the AUR repository:

$ mkdir -p ~/ox64/bluepill
$ cd ~/ox64/bluepill
$ git clone https://aur.archlinux.org/stm32flash.git
$ cd ~/ox64/bluepill/stm32flash
$ makepkg -si

Download the https://github.com/r2axz/bluepill-serial-monster[Bluepill Serial Monster] firmware:

$ mkdir -p ~/ox64/bluepill
$ cd ~/ox64/bluepill
$ wget https://github.com/r2axz/bluepill-serial-monster/releases/download/v2.6.4/bluepill-serial-monster.hex

Put the Bluepill into programming mode:

  • Set boot jumpers for booting from rom: Boot0=1, Boot1=0.
  • Connect it to a USB-Serial adapter with A9 to Rx, A10 to Tx, GND to GND, 3v3 to Vcc.
  • Apply power by plugging the USB cable to PC. Press the Reset button.

Find your USB serial adapter's device path with `ls /dev/ttyUSB* /dev/ttyACM*` (or similar); for the rest of this section we will refer to it as `/dev/tty[DEVICE]`. Upload the firmware:

$ cd ~/ox64/bluepill
$ sudo stm32flash -w bluepill-serial-monster.hex /dev/tty[DEVICE]

After upload, set boot jumpers for boot from flash: Boot0=0, Boot1=0. Disconnect the USB serial adapter from both the PC and Bluepill board.

Next, connect the Ox64 board to the Bluepill according to the following wiring diagram:

[cols="1,1,1"] |=== | Ox64 | Bluepill | /dev/tty

| uart0_Tx_GPIO14_pin1 | uart0_Rx_A3 | ACM1 for flashing

| uart0_Rx_GPIO15_pin2 | uart0_Tx_A2 | ACM1 for flashing

| Rxd_GPIO17_pin31 | uart1_Tx_A9 | ACM0 for serial console

| Txd_GPIO16_pin32 | uart1_Rx_A10 | ACM0 for serial console

| gnd_pin38 | GND |

| vbus5v_pin40 | 5V |

|===

With the Bluepill flashed and wired as per the instructions above, we have access to two of the Ox64's UART connections at the same time. This configuration eliminates the need to switch the physical connections for flashing or testing the system.

Connect the Bluepill to your computer's USB port and verify that we have access to all the serial ports we need:

$ ls /dev/ttyACM*

Expected result:

  • `/dev/ttyACM0` connects to the D0 core's (i.e. Linux's) serial console
  • `/dev/ttyACM1` is used for flashing (but also connects to the M0 core's serial console)
  • `/dev/ttyACM2` (unused)

Option 3: Generic UART adapter

image:/documentation/Ox64/images/ox64_pinout.png[Ox64 pinout,title="Ox64 pinout", 300, float="right"]

Check that your serial adapter is on the link:/documentation/Ox64/Further_information/Compatible_UARTs/[Compatible UARTs] list. You will (most likely) only have one serial interface available to you; unlike the previous options you will be using this same serial interface for both flashing and testing the system.

Find its device path with `ls /dev/ttyUSB* /dev/ttyACM*` (or similar); for the rest of this section we will refer to it as `/dev/tty[DEVICE]`.

You will also need a way of powering your Ox64. If your serial adapter has a 5V line, you can connect it to VBUS (pin 40). Otherwise, you can connect either the micro-B or the USB-C port on the Ox64 to any 5V power supply.

WARNING: Your serial adapter must use 3.3V logic levels.

Refer to the pinout image below. Connect your UART adapter as follows:

  • RX -> UART0_TX / GPIO14 / pin 1
  • TX -> UART0_RX / GPIO15 / pin 2
  • GND -> any ground (e. g. pin 3)

Proceed with the instructions in the sections that follow, up to and including <<flashing_the_ox64>> and <<flashing_the_microsd_card>>, but replace all occurrences of `/dev/ttyACM1` with `/dev/tty[DEVICE]`.

Next, power off the Ox64 and re-connect your UART adapter as follows:

  • RX -> TXD / GPIO16 / pin 32
  • TX -> RXD / GPIO17 / pin 31
  • GND -> any ground (e. g. pin 33)

Then, follow the instructions in <<booting_for_the_first_time>>, but replace all occurrences of `/dev/ttyACM0` with `/dev/tty[DEVICE]`. You should then have a working Linux system.

Download flashing tools

You have a choice of flashing software:

  • DevCube: GUI-based closed source flashing tool
  • CLI (`bflb-iot-tool`): command line open source flashing tool

DevCube installation

Download the latest DevCube flashing tool from BouffaloLab's website:

$ mkdir -p ~/ox64/devcube
$ cd ~/ox64/devcube
$ wget https://dev.bouffalolab.com/media/upload/download/BouffaloLabDevCube-v1.8.9.zip
$ unzip BouffaloLabDevCube-v1.8.9.zip
$ chmod u+x BLDevCube-ubuntu

If you did not create a link:#optional_create_a_combined_soc_image[combined image] you may need an older version of the DevCube. In that case, download v1.8.3 from one of the mirrors below:

Verify that your copy of `BouffaloLabDevCube-v1.8.3.zip` matches the hashes below:

  • SHA1: `0f2619e87d946f936f63ae97b0efd674357b1166`
  • SHA256: `e6e6db316359da40d29971a1889d41c9e97d5b1ff1a8636e9e6960b6ff960913`

CLI packages installation

Install `bflb-iot-tool` using your preferred method of managing PIP packages. One option is to set up a Python virtual environment as follows:

$ sudo apt install pipenv # for Debian-based systems
 # or
$ sudo pacman -S python-pipenv # for Arch Linux systems
$ cd ~/ox64/
$ pipenv install setuptools # install prerequisite of CLI flash tool
$ pipenv install bflb-iot-tool # install CLI flash tool
$ pipenv shell # activate virtual environment
$ # bflb-iot-tool --help # return info about the tool


NOTE: Each time you open a new terminal window you will need to `cd ~/ox64/` and re-run `pipenv shell` to reactivate the virtual environment.

Flashing the Ox64

Put the Ox64 into programming mode:

  • Press the BOOT button
  • Apply power or re-plug the USB cable
  • Release the BOOT button

CLI flashing method

Set up some environment variables to save typing them out later:

$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
 # or
$ cd ~/ox64/buildroot/output/images # if you built your own images
$ PORT=/dev/ttyACM1
$ BAUD=230400  # safe value for macOS, set to 2000000 for faster flashing on Linux

Finally, flash the Ox64. If you created a link:#optional_create_a_combined_soc_image[combined image] then run the command below:

$ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x0 --firmware bl808-combined.bin --single

Otherwise, run the following commands:

$ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x0 --firmware m0_lowload_bl808_m0.bin --single
$ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x100000 --firmware d0_lowload_bl808_d0.bin --single
$ bflb-iot-tool --chipname bl808 --interface uart --port $PORT --baudrate $BAUD --addr 0x800000 --firmware bl808-firmware.bin --single

If you get permission errors when running any of the commands above, run `ls -l /dev/tty[DEVICE]`, to find out which group is allowed to talk to serial ports and add your user to that group, with `sudo usermod -a -G [GROUP] $USER` (i.e. `dialout` for Debian or `uucp` for Arch Linux). Make sure you re-login. Running the commands as `root` is not recommended since this will make `bflb-iot-tool` create root-owned files in your home directory. You can now run `exit` from virtual environment.

BLDevCube flashing method

Open a new terminal window to run the DevCube flasher:

$ cd ~/ox64/devcube
$ ./BLDevCube-ubuntu

Select chip [BL808], press Finish, and configure BOTH the [MCU] and [IOT] tabs as follows. When you switch between tabs double check that they still match the settings below:

[cols="~,~"] |=== |Interface |UART

|Port/SN |`/dev/ttyACM1`

|UART rate |230400 (safe value for macOS, set to 2000000 for faster flashing on Linux) |===

If you created a link:#optional_create_a_combined_soc_image[combined image] then you only need to use the [IOT] tab:

  • Enable 'Single Download'
  • Image Address [0x0], [PATH to bl808-combined.bin]
  • Click 'Create & Download' and wait until it's done
  • Close DevCube

Otherwise, start in the [MCU] tab:

  • M0 Group[group0], Image Address [0x58000000], [PATH to m0_lowload_bl808_m0.bin]
  • D0 Group[group0], Image Address [0x58100000], [PATH to d0_lowload_bl808_d0.bin]
  • Click 'Create & Download' and wait until it's done

Then, switch to the [IOT] tab:

  • Enable 'Single Download'
  • Image Address [0x800000], [PATH to bl808-firmware.bin]
  • Click 'Create & Download' again and wait until it's done
  • Close DevCube

Erasing the microSD card

Make sure there are no signatures or partitions left, and overwrite the first sectors with zeroes. You can find the target device under `lsblk` command.

$ sudo wipefs /dev/[DEVICE]
$ sudo wipefs --all --force /dev/[DEVICE]*
$ sudo dd if=/dev/zero of=/dev/[DEVICE] status=progress bs=32768 count=1

Optionally you can zeroes the whole device:

$ sudo dd if=/dev/zero of=/dev/[DEVICE] status=progress bs=32768 count=$(expr $(lsblk -bno SIZE /dev/[DEVICE] | head -1) \/ 32768)

Flashing the microSD card

Insert the microSD card into your PC, locate its device under `lsblk` and write the image:

$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
 # or
$ cd ~/ox64/buildroot/output/images # if you built your own images
$ sudo dd if=sdcard.img of=/dev/[DEVICE] bs=1M status=progress conv=fsync

Booting for the first time

Power off your Ox64 and insert the microSD card.

Open a terminal window to connect to the D0 core’s (i.e. Linux’s) serial console:

$ minicom -b 2000000 -D /dev/ttyACM0

If you are using a Pico or Bluepill as your serial adapter, open another terminal window to to monitor the M0 core’s serial console (reminder: `/dev/ttyACM1` is the same port we previously used for flashing):

$ minicom -b 2000000 -D /dev/ttyACM1

Re-apply power to the Ox64.

On the main/D0 console (`/dev/ttyACM0`) you will see Linux booting up. When prompted, log in as `root` with no password. In case the SD card is missing or empty, you'll get a `Card did not respond to voltage select! : -110` error.

On the M0 console (`/dev/ttyACM1`) you'll see following messages until the sytem is fully loaded:


[I][MBOX] Mailbox IRQ Stats: [I][MBOX] Peripheral SDH (33): 0 [I][MBOX] Peripheral GPIO (60): 0 [I][MBOX] Unhandled Interupts: 0 Unhandled Signals 0


Once the system is running, the "MBOX" logs will abruptly disappear and you'll be able to manage the M0 multimedia core, i.e. wifi settings, etc. When prompted, type `help` to see available commands.

Connecting the Ox64 to your WiFi network

The simplest way to connect is to run the following command from the Linux console (i.e. `/dev/ttyACM0`):

$ blctl connect_ap <YourSSID> <YourPassword>

Wait for it to connect (if you're monitoring the M0 console on `/dev/ttyACM1` it should tell you when it's done), then run the following command from the Linux console:

$ udhcpc -i bleth0

Unfortunately the WiFi range leaves something to be desired. When you are performing the procedure above for the first time, move the Ox64 right next to your router. Once you are successfully connected, you can try experimenting with the maximum range.

For more information on using the `blctl` command, see https://github.com/bouffalolab/blwnet_xram[here].

Appendix

Adding Nuttx RTOS

In this section, we will set up our Ox64 to dual-boot both Linux and the NuttX real-time operating system. For more information see the https://nuttx.apache.org/docs/latest/platforms/risc-v/bl808/boards/ox64/index.html[official documentation].

First, write the normal Linux image to the SD card if you have not done so already. You can find the correct device under `lsblk`:

$ cd ~/ox64/openbouffalo/firmware # if you downloaded pre-built images
 # or
$ cd ~/ox64/buildroot/output/images # if you built your own images
$ sudo dd if=/sdcard.img of=/dev/[DEVICE] bs=1M conv=fsync status=progress

Run the following command to re-read the partition tables. Re-inserting the SD card works too:

$ sudo blockdev --rereadpt /dev/[DEVICE]

Download the NuttX image:

$ mkdir -p ~/ox64/nuttx
$ cd ~/ox64/nuttx
$ wget -O ImageNuttx https://github.com/lupyuen2/wip-pinephone-nuttx/releases/download/bl808d-1/Image

Mount the boot partition and make the required modifications:

$ sudo mount /dev/[DEVICE]2 /mnt
$ sudo cp ImageNuttx /mnt/
$ sudo tee -a /mnt/extlinux/extlinux.conf <<EOF
LABEL PINE64 OX64 Nuttx
       KERNEL ../ImageNuttx
       FDT ../bl808-pine64-ox64.dtb
EOF
$ sudo umount /mnt

Mount the rootfs and make the required modifications:

$ sudo mount /dev/[DEVICE]3 /mnt
$ sudo cp ImageNuttx /mnt/boot/
$ sudo tee -a /mnt/boot/extlinux/extlinux.conf <<EOF
LABEL PINE64 OX64 Nuttx
       KERNEL ../ImageNuttx
       FDT ../bl808-pine64-ox64.dtb
EOF
$ sudo umount /mnt

Enjoy your new Nuttx booting option!