Skip to content
This repository was archived by the owner on Jan 14, 2022. It is now read-only.

Commit ff51300

Browse files
authored
Merge pull request hypriot#96 from hypriot/blog-post-nvidia-jetson-nano-build-kernel-docker-optimized
Add blogpost about Nvidia Jetson Nano with Container optimized Linux kernel
2 parents f302e2c + 346401a commit ff51300

File tree

6 files changed

+286
-0
lines changed

6 files changed

+286
-0
lines changed
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
+++
2+
date = "2019-05-04T03:57:21+02:00"
3+
title = "NVIDIA Jetson Nano - Docker optimized Linux Kernel"
4+
draft = false
5+
more_link = "yes"
6+
Tags = ["Docker","Container","Linux","Kernel","Compatibility","Kubernetes","k8s","k3s","Networking","ipvlan"]
7+
Categories = ["Docker","Container","Linux","Kernel","Compatibility","Kubernetes","k8s","k3s","Networking","ipvlan"]
8+
9+
10+
+++
11+
12+
Despite the fact that the NVIDIA Jetson Nano DevKit comes with Docker Engine preinstalled and you can run containers just out-of-the-box on this great AI and Robotics enabled board, there are still some important kernel settings missing to run Docker Swarm mode, Kubernetes or k3s correctly.
13+
14+
![jetson-nano-board-docker-whale.jpg](/images/nvidia-jetson-nano-build-kernel-docker-optimized/jetson-nano-board-docker-whale.jpg)
15+
16+
So, let's try to fix this...
17+
18+
19+
<!--more-->
20+
21+
### Analyzing the Linux Kernel
22+
23+
In my last blogpost [Verify your Linux Kernel for Container Compatibility](https://blog.hypriot.com/post/verify-kernel-container-compatibility/), I already shared all the details how you can easily verify the Linux kernel for all Container related kernel settings. So, this first part of analyzing the capabilities of the stock Linux kernel 4.9.x provided by NVIDIA is already done and documented. And this was an easy task as well, so everyone who's interested in these details can repeat the task at his/her own device.
24+
25+
Let's recap what we did found. Especially there is one important setting which will be used for networking. This feature called "IPVLAN", is required for Docker Swarm mode and it's also used for networking in Kubernetes and k3s.
26+
27+
28+
### Building your own Linux Kernel
29+
30+
Anyway, even when we'd like to include or change only a single kernel setting, we have to customize the kernel configuration and have to compile and build our own Linux kernel. This is typically a common task for a desktop Linux system, but can be pretty ugly and cumbersome if you have to build the kernel for an Embedded Device.
31+
32+
When we look back to all the other NVIDIA Jetson boards, like the TK1, TX1 and TX2, this requires a second Linux machine, running Ubuntu 14.04 or 16.04 on an Intel CPU. Then setting up a complete build system for cross-compiling and all these stuff. Honestly, this is a well-known approach for an Embedded Developer, but the good thing now for the Jetson Nano DevKit this is not required any more.
33+
34+
Here the good news: you can customize and build your own Linux kernel directly on the Jetson Nano DevKit! You only need an internet connection and some time to perform all steps on your own. BTW, and this is another chance to learn something new.
35+
36+
37+
### Preparing the Build Environment
38+
39+
Before we're able to compile the Linux kernel on the Jetson Nano, we have to make sure we do have all required build tools installed. Here is all it takes, with a fast internet connection this is done within a few minutes only.
40+
41+
```bash
42+
$ sudo apt-get update
43+
$ sudo apt-get install -y libncurses5-dev
44+
```
45+
46+
47+
### Download Linux Kernel Sources for Jetson Nano
48+
49+
Next, we'll need to find and download the sources for the Linux kernel for the Jetson Nano DevKit directly from the NVIDIA website. The current version as writing this blogpost is NVIDIA Linux4Tegra Release r32.1 or short L4T 32.1. Just follow this link https://developer.nvidia.com/embedded/linux-tegra and select at topic "32.1 Driver Details" the referenced download link for "Jetson Nano", "SOURCES" and "BSP Sources".
50+
51+
We can also directly download this package to the Jetson Nano. But please be aware that this download link can change over time, so verify it carefully.
52+
```bash
53+
$ cd
54+
$ mkdir -p nano-bsp-sources
55+
$ cd nano-bsp-sources
56+
$ wget https://developer.download.nvidia.com/embedded/L4T/r32_Release_v1.0/jetson-nano/BSP/Jetson-Nano-public_sources.tbz2
57+
$ ls -alh Jetson-Nano-public_sources.tbz2
58+
-rw-rw-r-- 1 pirate pirate 133M Mar 16 06:46 Jetson-Nano-public_sources.tbz2
59+
```
60+
61+
Now extract the kernel source package "kernel_src.tbz2" from the downloaded file.
62+
```bash
63+
$ tar xvf Jetson-Nano-public_sources.tbz2 public_sources/kernel_src.tbz2
64+
$ mv public_sources/kernel_src.tbz2 ~/
65+
$ cd
66+
$ ls -alh ~/kernel_src.tbz2
67+
-rw-r--r-- 1 pirate pirate 117M Mar 13 08:45 /home/pirate/kernel_src.tbz2
68+
```
69+
70+
You may now free some disk space and remove all the downloads, as we don't need it any more.
71+
```bash
72+
$ rm -fr ~/nano-bsp-sources/
73+
```
74+
75+
Last step, please extract the kernel source tree.
76+
```bash
77+
$ cd
78+
$ tar xvf ./kernel_src.tbz2
79+
```
80+
81+
82+
### Compile the default Linux Kernel
83+
84+
Cool, we have now all the Linux kernel source tree for the Jetson Nano DevKit downloaded and extracted.
85+
86+
As the next step, I'd recommend to first compile the default unmodified kernel in order to verify that we do have all the build dependencies installed and this way, we'll also get familiar with the kernel compiling.
87+
88+
Before we can start the compile job, we have to make sure to use the correct kernel configuration file. This file ".config" is missing in the provided kernel source tree, but we can directly get it from our running Linux kernel on the Jetson Nano. This .config file can be found as kernel file at "/proc/config.gz" in a compressed form.
89+
```bash
90+
$ cd ~/kernel/kernel-4.9
91+
$ zcat /proc/config.gz > .config
92+
```
93+
94+
Now, let's verify the content of the Linux kernel .config file.
95+
```bash
96+
pirate@jetson-nano:~/kernel/kernel-4.9$ head -10 .config
97+
#
98+
# Automatically generated file; DO NOT EDIT.
99+
# Linux/arm64 4.9.140 Kernel Configuration
100+
#
101+
CONFIG_ARM64=y
102+
CONFIG_64BIT=y
103+
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
104+
CONFIG_MMU=y
105+
CONFIG_DEBUG_RODATA=y
106+
CONFIG_ARM64_PAGE_SHIFT=12
107+
...
108+
```
109+
110+
As you can see, it's a Kernel Configuration for Linux kernel version 4.9.140 and for ARM 64-bit architecture.
111+
112+
Start the kernel compile job. As we do have 4x cores available on the Nano, we'd like to keep the CPU busy and using 5x parallel compile tasks.
113+
```bash
114+
$ make prepare
115+
$ make modules_prepare
116+
117+
# Use 5x parallel compile tasks
118+
# Compile kernel as an image file
119+
$ time make -j5 Image
120+
...
121+
real 28m13,235s
122+
user 91m48,700s
123+
sys 7m46,240s
124+
125+
# List newly compiled kernel image
126+
$ ls -alh arch/arm64/boot/Image
127+
-rw-rw-r-- 1 pirate pirate 33M May 4 00:14 arch/arm64/boot/Image
128+
129+
# Compile all kernel modules
130+
$ time make -j5 modules
131+
...
132+
real 29m15,621s
133+
user 92m41,176s
134+
sys 8m18,404s
135+
```
136+
137+
The Nano CPU's are pretty busy while compiling the kernel and kernel modules.
138+
139+
![jetson-nano-board-compile-kernel.jpg](/images/nvidia-jetson-nano-build-kernel-docker-optimized/jetson-nano-board-compile-kernel.jpg)
140+
141+
The build/compile job will take around 60 minutes in total, but the good thing is, all happens directly on your Jetson Nano DevKit. No other expensive equipment is required at all, just an internet connection and some of your time.
142+
143+
144+
### Install our newly built Linux Kernel and Modules
145+
146+
After these pretty long compile jobs for generating our own Linux kernel and kernel modules, we are ready to install the kernel and verify if it's able to boot correctly. Therefore we should make a backup of the old kernel first, then install the new kernel and also install all newly built kernel modules.
147+
148+
Before we install the new kernel and boot the Jetson Nano, let's check the default Linux kernel version. Then we can compare it later to our own kernel.
149+
```bash
150+
pirate@jetson-nano:~$ uname -a
151+
Linux jetson-nano 4.9.140-tegra #1 SMP PREEMPT Wed Mar 13 00:32:22 PDT 2019 aarch64 aarch64 aarch64 GNU/Linux
152+
```
153+
154+
Here is also a ASCIINEMA recording of a `check-config.sh` verification done with the default kernel.
155+
[![asciicast](https://asciinema.org/a/244237.svg)](https://asciinema.org/a/244237?t=0:44)
156+
157+
As we can see, we do have a Linux kernel version "4.9.140-tegra". This one was compiled at "Wed Mar 13 00:32:22 PDT 2019" and it's the default kernel provided by NVIDIA for the Jetson Nano.
158+
159+
Now, install our new kernel and kernel modules.
160+
```bash
161+
# Backup the old kernel image file
162+
$ sudo cp /boot/Image /boot/Image.original
163+
164+
# Install modules and kernel image
165+
$ cd ~/kernel/kernel-4.9
166+
$ sudo make modules_install
167+
$ sudo cp arch/arm64/boot/Image /boot/Image
168+
169+
# Verify the kernel images
170+
pirate@jetson-nano:~/kernel/kernel-4.9$ ls -alh /boot/Image*
171+
-rw-r--r-- 1 root root 33M May 4 00:55 /boot/Image
172+
-rw-r--r-- 1 root root 33M May 4 00:49 /boot/Image.original
173+
```
174+
175+
Now, reboot the Nano and check the kernel again.
176+
```bash
177+
pirate@jetson-nano:~$ uname -a
178+
Linux jetson-nano 4.9.140 #1 SMP PREEMPT Sat May 4 00:12:56 CEST 2019 aarch64 aarch64 aarch64 GNU/Linux
179+
```
180+
181+
As you can see, our newly compiled kernel is working. The kernel version has changed to "4.9.140", note the missing trailing "-tegra" which indicates this build is a custom build. And the compile date/time has also changed to "Sat May 4 00:12:56 CEST 2019".
182+
183+
**Hint:** Please remember, every time you do change a kernel setting and compile a new kernel, you have to install the kernel image file AND the kernel modules.
184+
185+
186+
### Customizing the Linux Kernel Configuration
187+
188+
When it comes to the point to modify or customize the Linux kernel configuration, then this can get pretty complicated when you don't know where to start. First of all, it's a very bad idea to edit the .config file directly with an editor. Please, NEVER DO THIS - seriously!
189+
190+
The correct way to customize the kernel .config file is, to use the right tooling. One tool which is already built-in and available even in your bash shell (works also via ssh), is the tool `menuconfig`. Therefore we already installed the build dependency "libncurses5-dev" at the beginning.
191+
192+
I don't want to go into all details on how to use `menuconfig`, therefore here are the basic commands to start it and then I did recorded an ASCIINEMA to change the setting for "IPVLAN". I think then you'll should get a good idea how this works.
193+
194+
```bash
195+
# Backup the kernel config
196+
$ cd ~/kernel/kernel-4.9
197+
$ cp .config kernel.config.original
198+
199+
$ make menuconfig
200+
```
201+
202+
ASCIINEMA recording on how to include the "IPVLAN" kernel setting.
203+
[![asciicast](https://asciinema.org/a/244246.svg)](https://asciinema.org/a/244246?t=1:15)
204+
205+
Finally let's re-compile the kernel and the kernel modules and install them, like we did before.
206+
```bash
207+
$ cd ~/kernel/kernel-4.9
208+
209+
# Prepare the kernel build
210+
$ make prepare
211+
$ make modules_prepare
212+
213+
# Compile kernel image and kernel modules
214+
$ time make -j5 Image
215+
$ time make -j5 modules
216+
217+
# Install modules and kernel image
218+
$ sudo make modules_install
219+
$ sudo cp arch/arm64/boot/Image /boot/Image
220+
```
221+
222+
Reboot the Nano and check the kernel again.
223+
224+
225+
### Fast Forward - Fully Container Optimized Kernel Configuration
226+
227+
As you have learned here in this tutorial, you're now able to apply more and more settings to your kernel configuration. But this will take some time for sure.
228+
229+
In order to save you a lot of time and efforts, I've already optimized the Linux kernel in all details. Here you can find a public [Gist at Github](https://gist.githubusercontent.com/DieterReuter/a7d07445c9d62b45d9151c22b446c59b/) with my resulting kernel .config. You can download it directly to your Nano and compile your own Linux kernel with this configuration.
230+
231+
```bash
232+
# Download the fully container optimized kernel configuration file
233+
$ cd ~/kernel/kernel-4.9
234+
$ wget https://gist.githubusercontent.com/DieterReuter/a7d07445c9d62b45d9151c22b446c59b/raw/6decc91cc764ec0be8582186a34f60ea83fa89db/kernel.config.fully-container-optimized
235+
$ cp kernel.config.fully-container-optimized .config
236+
237+
# Prepare the kernel build
238+
$ make prepare
239+
$ make modules_prepare
240+
241+
# Compile kernel image and kernel modules
242+
$ time make -j5 Image
243+
$ time make -j5 modules
244+
245+
# Install modules and kernel image
246+
$ sudo make modules_install
247+
$ sudo cp arch/arm64/boot/Image /boot/Image
248+
```
249+
250+
Now, reboot the Nano and check the kernel again.
251+
```bash
252+
pirate@jetson-nano:~$ uname -a
253+
Linux jetson-nano 4.9.140 #2 SMP PREEMPT Sat May 4 02:17:23 CEST 2019 aarch64 aarch64 aarch64 GNU/Linux
254+
255+
pirate@jetson-nano:~$ ls -al /boot/Image*
256+
-rw-r--r-- 1 root root 34381832 May 4 03:13 /boot/Image
257+
-rw-r--r-- 1 root root 34048008 May 4 00:49 /boot/Image.original
258+
```
259+
260+
ASCIINEMA recording of the final run of `check-config.sh` with the fully optimized kernel for running Containers on the Jetson Nano DevKit.
261+
[![asciicast](https://asciinema.org/a/244250.svg)](https://asciinema.org/a/244250?t=1:13)
262+
263+
**Result: An almost perfect Linux kernel to run Containers on the NVIDIA Jetson Nano!**
264+
265+
![jetson-nano-board-docker-running2.jpg](/images/nvidia-jetson-nano-build-kernel-docker-optimized/jetson-nano-board-docker-running2.jpg)
266+
267+
268+
### Conclusion
269+
270+
As you could learn with this short, but highly technical tutorial, you're able to compile your own customized Linux kernel directly on the Jetson Nano DevKit without the need of an additional and maybe expensiv development machine. All can be done within an hour or two, and you have now the ability to change kernel settings whenever you want to. Just customize the kernel .config file, compile a new kernel and kernel modules and install it on your Nano.
271+
272+
This way you're now able to optimize the kernel for all your needs. For running Containers on the Nano with the help of Docker, Kubernetes or k3s, you're now well prepared and know how to do this by yourself.
273+
274+
Once the Linux kernel is fully optimized with all important Container related kernel settings, you can run Docker Swarm mode, Kubernetes and k3s with all features on that great ARM board from NVIDIA.
275+
276+
Finally, May the 4th be with You!
277+
![may-the-4th-be-with-you.jpg](/images/nvidia-jetson-nano-build-kernel-docker-optimized/may-the-4th-be-with-you.jpg)
278+
279+
280+
### Feedback, please
281+
282+
As always use the comments below to give us feedback and share it on Twitter or Facebook.
283+
284+
Please send us your feedback on our [Gitter channel](https://gitter.im/hypriot/talk) or tweet your thoughts and ideas on this project at [@HypriotTweets](https://twitter.com/HypriotTweets).
285+
286+
Dieter [@Quintus23M](https://twitter.com/Quintus23M)
358 KB
Loading
255 KB
Loading
266 KB
Loading
472 KB
Loading
120 KB
Loading

0 commit comments

Comments
 (0)