Building Turris OS

Hello, can you guys post updated guide on how to build Turris OS? It would be great if building it was just as simple as classic OpenWRT which I can build without any problems or strange errors. Both the official guide and the topic here [SOLVED] Cant build turris-os seem dated. The official guide is super confusing because it’s mixing at least four different approaches together.

Is it possible to build it for Marvell Armada 3700LP 88F3720 target (Espressobin)? I wasn’t able to find this option in the menuconfig.

Thanks for any help!

1 Like

They will not post an updated instruction set until 4.0 comes out which is “soon”. The base version of OpenWRT will be updated to the current version I’ve heard.

Best way to start compiling is to follow the instructions for setting up Vagrant on a Linux box or VM but make sure to download and install the latest version of Vagrant from the Vagrant website.

Once that is complete, there really isn’t much documentation other than building the default config. I’ve spent many hours trying to get a successful custom build but have failed so far. I got as close as building the OpenWRT portion. That is all make will do. The compile_fw script using the omnia and build_all=y variable in CLI will make the full medkit package which is what the default firmware is with the Fortis front end.


Well, the problem here was the missing target in Turris OS menuconfig - the Marvell chip. I wasn’t sure on what to do there.

I used vanilla OpenWRT and still had to manually patch the kernel to work with the WLE900VX WiFi card on Espressobin, got it working and then I ran out of time.

I tried vanilla openWRT 17 a few months back and as soon as I changed the assigned network address, it would disappear and not respond to the IP I set. I never tested the wifi… Or maybe I did. I can’t remember anymore. I was so fed up with it I took a break.

The Omnia target is under Marvel EBU by the way. … I think it’s EBU.

I’m back at trying to build this thing and ran into libfreecwmp source is shut down. Now I’m trying to figure out what I’m doing if I’m supposed to build from OpenWRT folder or Turris-OS folder.

Check this out:

I’m not sure why I didn’t find this before. Has the build script for the upcoming v4.0 as one of the branches. I’m loving the script so far. Has a help menu, options, and does everything for you. I’m quite impressed.

1 Like

Thanks, I’ll keep this in mind. I think I’ll try to build Turris OS again soon.

It’s only the OpenWRT portion and doesn’t have the medkit script yet. 4.0 doesn’t appear to be working yet as it gets into a boot loop. You might wait a bit longer. I’m a novice and don’t really understand how all the OpenWRT and foris parts go together but if helps, that’s great.

I built 18 and it made a medkit package but it’s only 6MB and just contains an IMG file. Did I miss something? Is it supposed to do that?

Hi naps1saps,

I found your message when I was trying to find some useful guide for build my own software for my Turris Omnia.

I am trying to follow the documentation, but it is not helping me very much. README.asciidoc gives some instructions like:

check compile_fw help for a list of available commands,

But I cannot see any file with that name in this folder: Turris / Turris OS / Turris Build · GitLab

I followed instructions from Turris Documentation but I was unable to accomplish. I found some scripts like compile_fw, but it doesn’t behave as described above. help is not a recognized parameter.

I will appreciate any help that you could provide me in order to build my hello-world for Turris Omnia.

With best regards


1 Like

Hey Sebastian,
try building your program just using the toolchain on your development computer. I wouldn’t try to build the entire OS just to make a Hello World.

Hi Kixorz,

Thank you for your fast response. Of course it makes no sense to build the entire OS for just an app. But I don’t know how to do it. My approach was to try to follow tutorials and guides as much as possible, and apply customizations later , but I couldn’t build entire OS either.

I was looking forward to achieve last part of the guide: Building single package

Thank you again for your time.

With best regards


It’s way too complicated to build the OS with the development package. You don’t need that to start.

Skip the package and use buildroot from OpenWRT to achieve the same result. See crosscompile and the Buildroot link inside. Keep in mind all OpenWRT tutorials and documents also very well apply to Turris OS.

It’s much easier to start building really simple and do the OS package as the final step.

1 Like

Thank you again for your kind help!

I was following the tutorial, but it has too many assumptions.
Anyway. I will follow your suggestion. Thank you again for your time and help

With best regards


1 Like

Hi again Kixorz,

I am sorry for disturbing you again. But I found myself a quite lost.
I was following instructions detailed on

  1. Follow the build instructions outlined in OpenWrt Buildroot – Usage
    1.1 Install the build system on the host like this:
    1.1.a. I installed build-essentials, git, etc etc on host.
    1.1.b. I downloaded the sources: git clone (should I clone turris omnia repository?)
    1.1.c. Specific branches: I didn’t select anything. Turris Omnia is based on OpenWRT 15.05, and there is no 15.05 branch at openwrt repository (should I do something here?)
    1.2. Follow the build instructions outlined in OpenWrt Buildroot – Usage
    1.2.a. I followed instructions, I was able to choose Target, etc. Everything fine so far
    1.2.b. When I make, after a couple of hours compiling, I receive some error (ld returned 1). I disgregad that error, since I don’t want to build entire FW.
  2. Locate the toolchain binaries in the staging_dir/toolchain-architecture_gcc-compilerver_uClibc-libcver/bin/ directory: I have the folder toolchain-arm_cortex-a9+vfpv3_gcc-7.3.0_musl_eabi (I was expecting something with Marvell EBU Armada, but I used anyway since it is the only folder close to requirement.
  3. Add that directory to the PATH environment variable: :ok:
  4. Download and unpack the code to be compiled, change into the unpacked directory… Where should I download my source code? Does it matter?
  5. Pass the host and build to the build system of the package to trigger cross-compile (I have no idea what host and build should I pass here…)

I will keep trying, but any help will be huge appreciated

With best regards


1 Like

It was recently renamed to compile_pkgs and it does just package compilation, then we generate lists and medkits using two other scripts. We didn’t updated documentation yet, sorry about that, I’ll take a look at it.

Thank you Miska for your answer.

I am still not sure if I should download files from openwrt repository or turris repository.

Would you mind to point me to the right repo?

With best regards


download the Omnia-related files here:
This server contains all the goodies - packages, toolchain and OS images.

What you’re looking for is the SDK: OpenWrt-SDK-mvebu_gcc-4.8-linaro_musl-1.1.15_eabi.Linux-x86_64.tar.bz2 This contains the compiler and OS-related files.
See this document:

This info has been mentioned here before, useful thread: Cross Compile - Howto?

1 Like


We have fixed the documentation, which you have found in the turris-build repository. That’s for Turris OS 4.0.
If you want to build packages for Turris OS 3.x then you need to follow

Dear Kixorz,

Thank you for your response.

Finally, I was able to compile my own Helloworld (and it works well in Turris Omnia). It was much simpler than I had though.

What I did:

  1. Download OpenWrt-SDK-mvebu_gcc-4.8-linaro_musl-1.1.15_eabi.Linux-x86_64.tar.bz2
  2. Uncompress it to OpenWrt-SDK (short folder name makes things easier)
  3. Copy my own source package [1] into OpenWrt-SDK/packages
    cp -R helloworld OpenWrt-SDK/package
  4. Change dir to OpenWrt-SDK and execute make package/helloworld/compile
    make package/helloworld/compile
  5. Find helloworld package in OpenWrt-SDK/bin/package…
    ls bin/mvebu-musl/packages/base/helloworld_1_mvebu.ipk
  6. Copy this package to my router
    scp bin/mvebu-musl/packages/base/helloworld_1_mvebu.ipk root@
  7. After login in the router, install the package
    dpkg install helloworld_1_mvebu.ipk
  8. Execute to test it!

[1] Here is my source package structure

helloworld/Makefile [2]
helloworld/src/Makefile [3]
helloworld/src/helloworld.c [4]

[2] Here is OpenWRT Package Makefile. It was copied from and I needed to change description part

# OpenWrt Makefile for helloworld program
# Most of the variables used here are defined in
# the include directives below. We just need to 
# specify a basic description of the package, 
# where to build our program, where to find 
# the source files, and where to install the 
# compiled program on the router. 
# Be very careful of spacing in this file.
# Indents should be tabs, not spaces, and 
# there should be no trailing whitespace in
# lines that are not commented.

include $(TOPDIR)/

# Name and release number of this package

# This specifies the directory where we're going to build the program.  
# The root build directory, $(BUILD_DIR), is by default the build_mipsel 
# directory in your OpenWrt SDK directory

include $(INCLUDE_DIR)/

# Specify package information for this program. 
# The variables defined here should be self explanatory.
# If you are running Kamikaze, delete the DESCRIPTION 
# variable below and uncomment the Kamikaze define
# directive for the description below
define Package/helloworld
	TITLE:=Helloworld -- prints a snarky message
#	If you can't figure out what this program does, \\\
#	you're probably brain-dead and need immediate \\\
#	medical attention.

# Uncomment portion below for Kamikaze and delete DESCRIPTION variable above
define Package/helloworld/description
	If you can't figure out what this program does, you're probably
	brain-dead and need immediate medical attention.

# Specify what needs to be done to prepare for building the package.
# In our case, we need to copy the source files to the build directory.
# This is NOT the default.  The default uses the PKG_SOURCE_URL and the
# PKG_SOURCE which is not defined here to download the source from the web.
# In order to just build a simple program that we have just written, it is
# much easier to do it this way.
define Build/Prepare
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) ./src/* $(PKG_BUILD_DIR)/

# We do not need to define Build/Configure or Build/Compile directives
# The defaults are appropriate for compiling a simple program such as this one

# Specify where and how to install the program. Since we only have one file, 
# the helloworld executable, install it by copying it to the /bin directory on
# the router. The $(1) variable represents the root directory on the router running 
# OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install 
# directory if it does not already exist.  Likewise $(INSTALL_BIN) contains the 
# command to copy the binary file from its current location (in our case the build
# directory) to the install directory.
define Package/helloworld/install
	$(INSTALL_DIR) $(1)/bin
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/bin/

# This line executes the necessary commands to compile our program.
# The above define directives specify all the information needed, but this
# line calls BuildPackage which in turn actually uses this information to
# build a package.
$(eval $(call BuildPackage,helloworld))

[3] Here is the GNU Makefile. I took this also from . Please replace this-is-a-tab with a real tabulation

# build helloworld executable when user executes "make"
helloworld: helloworld.o
this-is-a-tab $(CC) $(LDFLAGS) helloworld.o -o helloworld
helloworld.o: helloworld.c
this-is-a-tab $(CC) $(CFLAGS) -c helloworld.c
# remove object files and executable when user executes "make clean"
this-is-a-tab rm *.o helloworld

[4] Here is the helloworld source code, just for your reference.

* Helloworld.c
#include <stdio.h>;
int main(void)
    printf("Hello world!\n\n");
    return 0;

Thank you Kixorz and Miska for your time and support.

With best regards