├── LICENSE
├── README.md
├── images
├── bee42-logo.jpg
└── bee42-workshop.jpg
├── part1-bootloader.md
├── part2-kernel.md
├── part3-root-filesystem.md
└── part4-sd-card-image.md
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Dieter Reuter
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Workshop:
3 | # Building a 64bit Docker OS for the Raspberry Pi 3
4 |
5 | In this "short" workshop I'm going through all the steps to build a complete 64bit operating system for the Raspberry Pi 3. This 64bit HypriotOS is mainly focused on running Docker containers easily on this popular DIY and IoT device.
6 |
7 | You'll see that I'm using Docker heavily for each and every build step, because it really helps us a lot to run a local build with [Docker-for-Mac](https://docs.docker.com/docker-for-mac/) or later on the cloud build servers at [Travis CI](https://travis-ci.org).
8 |
9 | 
10 |
11 | This workshop is sponsored by [bee24 solutions](http://bee42.com)
12 |
13 |
14 | ### Background and Contents
15 |
16 | As you may already know, a complete Linux operating system consists of several important building blocks and I'd like to show you how to build all of these step by step.
17 |
18 | For this purpose I'm not going to reinvent the wheel and so I'll reuse all of the existing parts which are already published by the Raspberry Pi Organisation, by the Debian Linux project and will add some more glue code.
19 |
20 | At the end you should have learned how to build all the necessary parts and how to automatically create a finished SD card image which could be flashed on an empty SD card. Then boot your Raspberry Pi 3 with and in less than a minute you have a fully running Docker Engine on a Debian-based 64bit Linux OS.
21 |
22 | Here is a short overview of the contents of the workshop:
23 |
24 | * [Part 1: Bootloader](/part1-bootloader.md)
25 |
26 | * [Part 2: Kernel](/part2-kernel.md)
27 |
28 | * [Part 3: Root Filesystem](/part3-root-filesystem.md)
29 |
30 | * [Part 4: SD Card Image](/part4-sd-card-image.md)
31 |
32 | So, that's enough for explaining the background of this workshop. For more informations
33 | please follow along the details I'll publish on the coming tweets at Twitter and in the
34 | GitHub repos until all the parts of this workshop are finished and available as OpenSource.
35 |
36 | Please be aware that this OS is in a development phase and far from being perfect.
37 | So you are encouraged to help me with reporting issues and filing pull-requests to
38 | add features and fix bugs.
39 |
40 |
41 | ### Raspberry Pi 3 Model B
42 |
43 | **Specification**
44 |
45 | 
46 |
47 | Even more technical specs can be found at [Wikipedia](https://en.wikipedia.org/wiki/Raspberry_Pi) or in this detailed [MagPi article](https://www.raspberrypi.org/magpi/raspberry-pi-3-specs-benchmarks/).
48 |
49 | --
50 |
51 | 
52 |
53 | --
54 | MIT License
55 |
56 | Copyright (c) 2017 Dieter Reuter
57 |
--------------------------------------------------------------------------------
/images/bee42-logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DieterReuter/workshop-raspberrypi-64bit-os/878fd9bfba613bbdd77c91416077c694d204f987/images/bee42-logo.jpg
--------------------------------------------------------------------------------
/images/bee42-workshop.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DieterReuter/workshop-raspberrypi-64bit-os/878fd9bfba613bbdd77c91416077c694d204f987/images/bee42-workshop.jpg
--------------------------------------------------------------------------------
/part1-bootloader.md:
--------------------------------------------------------------------------------
1 |
2 | # Part 1: Bootloader
3 |
4 | In order to know which essential files are needed to boot the Raspberry Pi from a SD card we have to dig a little bit deeper into the boot process itself. The boot process is almost the same for each and every Raspberry Pi model, so let's read this as a basic primer.
5 |
6 |
7 | ## Raspberry Pi Boot Process
8 |
9 | Booting a Raspberry Pi is a little bit different because the CPU is offline from the beginning and the SoC (system on a chip) starts the GPU first which initializes the important system components and controls or better starts the low level boot process.
10 |
11 | * **First Stage Bootloader** -
12 | The first stage bootloader is located in the ROM section of the SoC, so it is baked-in into the hardware chip. It mounts the FAT32 boot section/partition of the SD card in order to have access to load the necessary files like the second stage bootloader.
13 |
14 | * **Second Stage Bootloader** -
15 | The second stage bootloader will be loaded from the file "bootcode.bin" which contains the GPU code to start the GPU and loading the GPU firmware. So you can see that "bootcode.bin" contains just GPU specific code and will be provided as a closed-source binary blob.
16 |
17 | * **GPU Firmware** -
18 | The GPU firmware itself is loaded from the file "start.elf" and enables the GPU to load and run ARM specific user code for the CPU like our Linux kernel which we need to start our Linux operating system.
19 |
20 | * **User Code** -
21 | The user code will be run on the CPU and is therefore compiled for the specific ARM processor. Normally this is the Linux kernel which is compiled for ARMv6 or ARMv7 architecture for running Raspbian, but we're going to use a Linux kernel for ARMv8 (or ARM64) which is also known as the AARCH64 architecture.
22 |
23 | I'm just touching the basic parts here and if you're interested in all the details you can find the boot process explained in more detail at http://elinux.org/RPi_Software or read the latest documentation about the [Raspberry Pi Boot Modes](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/).
24 |
25 |
26 | ## 32bit or 64bit, Who knows?
27 |
28 | The bootloader software from the Raspberry Pi repo is exactly the same to use for 32 and 64bit systems. The hardware will be checked at boot time, so the bootloader knows the correct hardware SOC and if it's capable to run 64bit code or not. Then it tries to load the 64bit kernel only on RPi3. If there's no 64bit kernel it falls back to load a 32bit kernel and so on. Same thing works for ARMv8, ARMv7 and ARMv6 SOCs.
29 |
30 | For us this automatic detection is pretty cool, because it just magically works and gives us the flexibility to build a SD card with different kernel version that works on all Pi models from 1, 2, 3, Zero and Zero W.
31 |
32 |
33 | ## Minimum Boot Files
34 |
35 | As we learned about the boot process, we do have only a few requirements to successfully boot a Raspberry Pi from a SD card:
36 |
37 | * **FAT32 filesystem** -
38 | will be mounted later as "/boot" in Linux
39 | * **File "bootcode.bin"** - Second Stage Bootloader
40 | * **File "start.elf"** - GPU Firmware
41 | * **File "fixup.dat"** - (optional) used to configure the SDRAM partition between GPU and CPU
42 |
43 | And next the user code like the Linux kernel to bring our system to life.
44 |
45 | > These are really the minimum required bootfiles to boot a Raspberry Pi from SD card:
46 |
47 | > "bootcode.bin", "start.elf", "fixup.dat", "kernel.img"
48 |
49 | To be honest, we do need a few more files for starting and configuring the Linux kernel and to access the serial UART console. So I'm listing here the bare minimum bootfiles to really boot into our Linux kernel and so we can see the kernel logs appear on the serial UART console.
50 | ```
51 | $ ls -al
52 | total 15284
53 | drwxr-xr-x 2 root root 16384 Mar 3 11:12 .
54 | drwxr-xr-x 21 root root 4096 Jul 3 2014 ..
55 | -rwxr-xr-x 1 root root 17253 Mar 1 17:42 bcm2710-rpi-3-b.dtb
56 | -rwxr-xr-x 1 root root 50268 Mar 1 16:58 bootcode.bin
57 | -rwxr-xr-x 1 root root 215 Mar 1 18:14 cmdline.txt
58 | -rwxr-xr-x 1 root root 50 Mar 3 11:12 config.txt
59 | -rwxr-xr-x 1 root root 6640 Mar 1 16:58 fixup.dat
60 | -rwxr-xr-x 1 root root 12704256 Mar 1 17:42 kernel8.img
61 | -rwxr-xr-x 1 root root 2841412 Mar 1 16:58 start.elf
62 | ```
63 |
64 |
65 | ## Where to get the bootloader files?
66 |
67 | As I already mentioned before, these bootloader files are provided as closed-source binary blobs directly from the Raspberry Pi Foundation and can be downloaded from the "boot" section/folder of the Raspberry Pi Firmware repo [raspberrypi/firmware on GitHub](https://github.com/raspberrypi/firmware/tree/master/boot).
68 |
69 |
70 | ## Let's build a bootloader package
71 |
72 | Now it's time to build our first component, the "rpi-bootloader" which contains just the bootfiles for the Raspberry Pi. And for easy use we're just going to create a tarball with the essential bootfiles.
73 | > As these bootfiles are not specific to a Raspberry Pi 3 only, we could possibly reuse this package later for all the other Raspberry Pi models as well.
74 |
75 | I've already prepared a GitHub repo to create a tarball https://github.com/dieterreuter/rpi-bootloader.
76 |
77 |
78 | ### How the build process works
79 |
80 | The build process uses Docker Compose to build a Docker Image first with a complete build environment based upon Debian/Jessie. So you can see, this build always run in a well defined environment. It's running in an isolated Linux with Debian/Jessie inside of a Docker container. In this case we don't have to install anything (except Docker itself or on macOS Docker-for-Mac) on our host machine.
81 |
82 | As you can see, I'm using the command `docker-compose build` to build the Docker Image and later on I'm issuing a single build run with the command `docker-compose run builder`. That's all.
83 | ```
84 | $ cat build.sh
85 | #!/bin/bash
86 | set -e
87 |
88 | docker-compose build
89 | docker-compose run builder
90 | ```
91 |
92 | For easier usage I created a script "build.sh" with these two commands, so we can just invoke a new build with a single command only.
93 | ```
94 | $ ./build.sh
95 | ```
96 |
97 | The build results can be found in a sub-folder `./builds/`, for each new build the script `build-tarball.sh` is creating a new build folder with an individual version based upon the date+time of the current build. So we can run subsequent builds and keep all the old build artefacts.
98 | ```
99 | $ tree builds/
100 | builds/
101 | └── 20170303-121340
102 | ├── rpi-bootloader.tar.gz
103 | └── rpi-bootloader.tar.gz.sha256
104 |
105 | 1 directory, 2 files
106 | ```
107 |
108 |
109 | ### Create a Travis CI build job
110 |
111 | Most of the times it is easier and more reliable to use a CI (continous integration) system to run the build process on a cloud server, so I'm going to use [Travis CI](https://travis-ci.org).
112 |
113 | I just created the necessary Travis configuration file `.travis.yml` with some special settings.
114 | ```
115 | $ cat .travis.yml
116 | sudo: required
117 | services:
118 | - docker
119 | language: bash
120 | script:
121 | - ./travis-build.sh
122 | after_success:
123 | - ls -al builds/$BUILD_NR/*
124 | branches:
125 | only:
126 | - master
127 | except:
128 | - /^v\d.*$/
129 | ```
130 |
131 | With the help of an extra Travis build script `travis-build.sh` I'm now able to upload the build artefacts of every successful build as a new GitHub release at https://github.com/DieterReuter/rpi-bootloader/releases. This makes it very easy to consume these build artefacts later in another build process and I do have all the complete and detailed build logs available for future reference.
132 |
133 |
134 | ## Recap
135 |
136 | We talked about the Raspberry Pi boot process in detail and have shown the minimum required bootfiles.
137 |
138 | Then we've built a GitHub repo with a complete automated build process to fetch all files from the original Raspberry Pi Firmware repo and then building a versioned tarball. We can run the build process for development locally on macOS with the help of [Docker-for-Mac](https://docs.docker.com/docker-for-mac/) and later on the cloud build servers at [Travis CI](https://travis-ci.org).
139 |
140 | At the end we can just use the produced tarball "rpi-bootloader.tar.gz" in order to copy all the bootfiles to a SD card to get the latest version.
141 |
142 | ```
143 | $ tar vtf builds/20170303-121340/rpi-bootloader.tar.gz
144 | -rw-r--r-- 0 root root 1494 Mar 3 13:14 boot/LICENCE.broadcom
145 | -rw-r--r-- 0 root root 50268 Mar 3 13:14 boot/bootcode.bin
146 | -rw-r--r-- 0 root root 6646 Mar 3 13:14 boot/fixup.dat
147 | -rw-r--r-- 0 root root 2558 Mar 3 13:14 boot/fixup_cd.dat
148 | -rw-r--r-- 0 root root 9777 Mar 3 13:14 boot/fixup_db.dat
149 | -rw-r--r-- 0 root root 9775 Mar 3 13:14 boot/fixup_x.dat
150 | -rw-r--r-- 0 root root 2846692 Mar 3 13:14 boot/start.elf
151 | -rw-r--r-- 0 root root 654980 Mar 3 13:14 boot/start_cd.elf
152 | -rw-r--r-- 0 root root 4983140 Mar 3 13:14 boot/start_db.elf
153 | -rw-r--r-- 0 root root 3929604 Mar 3 13:14 boot/start_x.elf
154 | ```
155 |
156 | To create a bootable SD card we now have to format a SD card with FAT32 and have to copy all the files from the "/boot" folder into the root directory of the SD card. But as we don't have any meaningful user code embedded yet, like "kernel8.img", we won't see anything on an attached HDMI monitor nor on the serial UART console. This will be covered in detail in [Part 2 - Kernel](/part2-kernel.md).
157 |
158 | --
159 |
160 | 
161 |
162 | --
163 | MIT License
164 |
165 | Copyright (c) 2017 Dieter Reuter
166 |
--------------------------------------------------------------------------------
/part2-kernel.md:
--------------------------------------------------------------------------------
1 |
2 | # Part 2: Kernel
3 |
4 | ## Using the Linux kernel
5 |
6 | At the end of the boot process the bootloader will automatically detect the CPU model and tries to load and run a pre-defined Linux kernel. As the first Raspberry Pi uses an ARMv6 CPU and later on with the Raspberry Pi 2 an ARMv7 CPU, the bootloader can load both different kernels. Here are the default filenames we could use for these different kernel versions:
7 |
8 | * **kernel.img** - for ARMv6 (Raspberry 1, Zero, Zero W)
9 | * **kernel7.img** - for ARMv7 (Raspberry 2, 3 in 32bit mode)
10 | * **kernel8.img** - for ARMv8,ARM64,AARCH64 (Raspberry 3 in 64bit mode)
11 |
12 | As we're going right into a 64bit Linux system, we're using "kernel8.img" as our user code to be started directly through the bootloader. To be honest there are some more additional configuration files which will be needed to start and configure our Linux kernel in the right way.
13 |
14 | * **kernel8.img** - the 64bit kernel for the Raspberry Pi 3
15 | * **bcm2710-rpi-3-b.dtb** - device tree binary Linux kernel configuration
16 | * **config.txt** - configuration file read by the bootloader
17 | * **cmdline.txt** - kernel commandline parameters
18 |
19 | Now we do have these minimal bootfiles which consists on the bootloader itself, the Linux kernel as user code and some configuration files. As soon as we put these on a SD card with FAT32 format, our Raspberry Pi 3 can be booted from and will show detailed kernel logs while booting on the serial UART console.
20 | ```
21 | $ ls -al
22 | total 15284
23 | drwxr-xr-x 2 root root 16384 Mar 3 11:12 .
24 | drwxr-xr-x 21 root root 4096 Jul 3 2014 ..
25 | -rwxr-xr-x 1 root root 17253 Mar 1 17:42 bcm2710-rpi-3-b.dtb
26 | -rwxr-xr-x 1 root root 50268 Mar 1 16:58 bootcode.bin
27 | -rwxr-xr-x 1 root root 215 Mar 1 18:14 cmdline.txt
28 | -rwxr-xr-x 1 root root 50 Mar 3 11:12 config.txt
29 | -rwxr-xr-x 1 root root 6640 Mar 1 16:58 fixup.dat
30 | -rwxr-xr-x 1 root root 12704256 Mar 1 17:42 kernel8.img
31 | -rwxr-xr-x 1 root root 2841412 Mar 1 16:58 start.elf
32 | ```
33 |
34 | One important part to use the serial UART console is the configuration of `enable_uart=1` in "config.txt".
35 | ```
36 | $ cat config.txt
37 | # enable UART console on GPIO pins
38 | enable_uart=1
39 | ```
40 |
41 | And there are some more parameters to set in the kernel commandline like `console=tty1`, `console=ttyAMA0,115200` and `kgdboc=ttyAMA0,115200`.
42 | ```
43 | $ cat cmdline.txt
44 | +dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 cgroup_enable=cpuset cgroup_enable=memory swapaccount=1 elevator=deadline fsck.repair=yes rootwait console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
45 | ```
46 |
47 | Here are the kernel logs (seen on serial UART console) of a boot attempt with such a 64bit Linux kernel but without having a root filesystem available on the SD card.
48 | ```
49 | [ 0.000000] Booting Linux on physical CPU 0x0
50 | [ 0.000000] Linux version 4.9.13-bee42-v8 (root@1aca9db9a114) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #1 SMP PREEMPT Wed Mar 1 17:38:31 UTC 2017
51 | [ 0.000000] Boot CPU: AArch64 Processor [410fd034]
52 | [ 0.000000] efi: Getting EFI parameters from FDT:
53 | [ 0.000000] efi: UEFI not found.
54 | [ 0.000000] cma: Reserved 8 MiB at 0x0000000007400000
55 | [ 0.000000] percpu: Embedded 22 pages/cpu @fffffffc07f7d000 s52632 r8192 d29288 u90112
56 | [ 0.000000] Detected VIPT I-cache on CPU0
57 | [ 0.000000] CPU features: enabling workaround for ARM erratum 845719
58 | [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 32256
59 | [ 0.000000] Kernel command line: 8250.nr_uarts=1 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2708_fb.fbswap=1 vc_mem.mem_base=0xec00000 vc_mem.mem_size=0x10000000 +dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 cgroup_enable=cpuset cgroup_enable=memory swapaccount=1 elevator=deadline fsck.repair=yes rootwait console=ttyS0,115200 kgdboc=ttyS0,115200
60 | [ 0.000000] PID hash table entries: 512 (order: 0, 4096 bytes)
61 | [ 0.000000] Dentry cache hash table entries: 16384 (order: 5, 131072 bytes)
62 | [ 0.000000] Inode-cache hash table entries: 8192 (order: 4, 65536 bytes)
63 | [ 0.000000] Memory: 92532K/131072K available (6588K kernel code, 758K rwdata, 2384K rodata, 2624K init, 830K bss, 30348K reserved, 8192K cma-reserved)
64 | [ 0.000000] Virtual kernel memory layout:
65 | [ 0.000000] modules : 0xffffff8000000000 - 0xffffff8008000000 ( 128 MB)
66 | [ 0.000000] vmalloc : 0xffffff8008000000 - 0xffffffbebfff0000 ( 250 GB)
67 | [ 0.000000] .text : 0xffffff99ee680000 - 0xffffff99eecf0000 ( 6592 KB)
68 | [ 0.000000] .rodata : 0xffffff99eecf0000 - 0xffffff99eef50000 ( 2432 KB)
69 | [ 0.000000] .init : 0xffffff99eef50000 - 0xffffff99ef1e0000 ( 2624 KB)
70 | [ 0.000000] .data : 0xffffff99ef1e0000 - 0xffffff99ef29da00 ( 759 KB)
71 | [ 0.000000] .bss : 0xffffff99ef29da00 - 0xffffff99ef36d214 ( 831 KB)
72 | [ 0.000000] fixed : 0xffffffbefe7fd000 - 0xffffffbefec00000 ( 4108 KB)
73 | [ 0.000000] PCI I/O : 0xffffffbefee00000 - 0xffffffbeffe00000 ( 16 MB)
74 | [ 0.000000] vmemmap : 0xffffffbf00000000 - 0xffffffc000000000 ( 4 GB maximum)
75 | [ 0.000000] 0xffffffbff0000000 - 0xffffffbff0200000 ( 2 MB actual)
76 | [ 0.000000] memory : 0xfffffffc00000000 - 0xfffffffc08000000 ( 128 MB)
77 | [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
78 | [ 0.000000] Preemptible hierarchical RCU implementation.
79 | [ 0.000000] Build-time adjustment of leaf fanout to 64.
80 | [ 0.000000] NR_IRQS:64 nr_irqs:64 0
81 | [ 0.000000] Failed to get local register map. FIQ is disabled for cpus > 1
82 | [ 0.000000] arm_arch_timer: Architected cp15 timer(s) running at 19.20MHz (phys).
83 | [ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns
84 | [ 0.000005] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns
85 | [ 0.000229] Console: colour dummy device 80x25
86 | [ 0.001448] console [tty1] enabled
87 | [ 0.001494] Calibrating delay loop (skipped), value calculated using timer frequency.. 38.40 BogoMIPS (lpj=19200)
88 | [ 0.001557] pid_max: default: 32768 minimum: 301
89 | [ 0.001879] Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
90 | [ 0.001936] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes)
91 | [ 0.003015] ftrace: allocating 22746 entries in 89 pages
92 | [ 0.061760] ASID allocator initialised with 65536 entries
93 | [ 0.069681] EFI services will not be available.
94 | [ 0.078673] Detected VIPT I-cache on CPU1
95 | [ 0.078736] CPU1: Booted secondary processor [410fd034]
96 | [ 0.085780] Detected VIPT I-cache on CPU2
97 | [ 0.085825] CPU2: Booted secondary processor [410fd034]
98 | [ 0.092897] Detected VIPT I-cache on CPU3
99 | [ 0.092939] CPU3: Booted secondary processor [410fd034]
100 | [ 0.093043] Brought up 4 CPUs
101 | [ 0.093235] SMP: Total of 4 processors activated.
102 | [ 0.093274] CPU features: detected feature: 32-bit EL0 Support
103 | [ 0.093375] CPU: All CPU(s) started at EL2
104 | [ 0.093436] alternatives: patching kernel code
105 | [ 0.094492] devtmpfs: initialized
106 | [ 0.111145] DMI not present or invalid.
107 | [ 0.111535] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
108 | [ 0.111608] futex hash table entries: 1024 (order: 5, 131072 bytes)
109 | [ 0.112284] pinctrl core: initialized pinctrl subsystem
110 | [ 0.113030] NET: Registered protocol family 16
111 | [ 0.124301] cpuidle: using governor menu
112 | [ 0.124751] vdso: 2 pages (1 code @ ffffff99eecf7000, 1 data @ ffffff99ef1e4000)
113 | [ 0.124819] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
114 | [ 0.126863] DMA: preallocated 256 KiB pool for atomic allocations
115 | [ 0.126996] Serial: AMBA PL011 UART driver
116 | [ 0.131843] bcm2835-mbox 3f00b880.mailbox: mailbox enabled
117 | [ 0.132710] uart-pl011 3f201000.serial: could not find pctldev for node /soc/gpio@7e200000/uart0_pins, deferring probe
118 | [ 0.185768] HugeTLB registered 2 MB page size, pre-allocated 0 pages
119 | [ 0.186779] bcm2835-dma 3f007000.dma: DMA legacy API manager at ffffff800804b000, dmachans=0x1
120 | [ 0.189271] SCSI subsystem initialized
121 | [ 0.189495] usbcore: registered new interface driver usbfs
122 | [ 0.189625] usbcore: registered new interface driver hub
123 | [ 0.189792] usbcore: registered new device driver usb
124 | [ 0.190077] dmi: Firmware registration failed.
125 | [ 0.191243] raspberrypi-firmware soc:firmware: Attached to firmware from 2017-02-26 20:30
126 | [ 0.192990] clocksource: Switched to clocksource arch_sys_counter
127 | [ 0.268406] VFS: Disk quotas dquot_6.6.0
128 | [ 0.268537] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
129 | [ 0.268826] FS-Cache: Loaded
130 | [ 0.269259] CacheFiles: Loaded
131 | [ 0.284203] NET: Registered protocol family 2
132 | [ 0.285250] TCP established hash table entries: 1024 (order: 1, 8192 bytes)
133 | [ 0.285321] TCP bind hash table entries: 1024 (order: 2, 16384 bytes)
134 | [ 0.285390] TCP: Hash tables configured (established 1024 bind 1024)
135 | [ 0.285523] UDP hash table entries: 256 (order: 1, 8192 bytes)
136 | [ 0.285583] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
137 | [ 0.285905] NET: Registered protocol family 1
138 | [ 0.286524] RPC: Registered named UNIX socket transport module.
139 | [ 0.286561] RPC: Registered udp transport module.
140 | [ 0.286592] RPC: Registered tcp transport module.
141 | [ 0.286622] RPC: Registered tcp NFSv4.1 backchannel transport module.
142 | [ 0.287909] hw perfevents: enabled with armv8_pmuv3 PMU driver, 7 counters available
143 | [ 0.290869] workingset: timestamp_bits=46 max_order=15 bucket_order=0
144 | [ 0.312215] FS-Cache: Netfs 'nfs' registered for caching
145 | [ 0.313373] NFS: Registering the id_resolver key type
146 | [ 0.313442] Key type id_resolver registered
147 | [ 0.313477] Key type id_legacy registered
148 | [ 0.316468] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
149 | [ 0.316691] io scheduler noop registered
150 | [ 0.316729] io scheduler deadline registered (default)
151 | [ 0.316813] io scheduler cfq registered
152 | [ 0.322871] BCM2708FB: allocated DMA memory c7450000
153 | [ 0.322946] BCM2708FB: allocated DMA channel 0 @ ffffff800804b000
154 | [ 0.329911] Console: switching to colour frame buffer device 82x26
155 | [ 0.334635] Serial: 8250/16550 driver, 1 ports, IRQ sharing enabled
156 | [ 0.337232] console [ttyS0] disabled
157 | [ 0.338686] 3f215040.serial: ttyS0 at MMIO 0x0 (irq = 61, base_baud = 31224999) is a 16550
158 | [ 1.028053] console [ttyS0] enabled
159 | [ 1.033775] KGDB: Registered I/O driver kgdboc
160 | [ 1.045837] bcm2835-rng 3f104000.rng: hwrng registered
161 | [ 1.052882] Unable to detect cache hierarchy from DT for CPU 0
162 | [ 1.079034] brd: module loaded
163 | [ 1.096254] loop: module loaded
164 | [ 1.100870] Loading iSCSI transport class v2.0-870.
165 | [ 1.107931] usbcore: registered new interface driver smsc95xx
166 | [ 1.115233] dwc_otg: version 3.00a 10-AUG-2012 (platform bus)
167 | [ 1.348566] Core Release: 2.80a
168 | [ 1.353150] Setting default values for core params
169 | [ 1.359424] Finished setting default values for core params
170 | [ 1.566921] Using Buffer DMA mode
171 | [ 1.571695] Periodic Transfer Interrupt Enhancement - disabled
172 | [ 1.579074] Multiprocessor Interrupt Enhancement - disabled
173 | [ 1.586210] OTG VER PARAM: 0, OTG VER FLAG: 0
174 | [ 1.592098] Dedicated Tx FIFOs mode
175 | [ 1.597506] WARN::dwc_otg_hcd_init:1053: FIQ DMA bounce buffers: virt = 0x08111000 dma = 0xc7444000 len=9024
176 | [ 1.610400] FIQ FSM acceleration enabled for :
177 | [ 1.610400] Non-periodic Split Transactions
178 | [ 1.610400] Periodic Split Transactions
179 | [ 1.610400] High-Speed Isochronous Endpoints
180 | [ 1.610400] Interrupt/Control Split Transaction hack enabled
181 | [ 1.640038] WARN::hcd_init_fiq:486: MPHI regs_base at 0x080fa000
182 | [ 1.647629] dwc_otg 3f980000.usb: DWC OTG Controller
183 | [ 1.654128] dwc_otg 3f980000.usb: new USB bus registered, assigned bus number 1
184 | [ 1.663064] dwc_otg 3f980000.usb: irq 15, io mem 0x00000000
185 | [ 1.670198] Init: Port Power? op_state=1
186 | [ 1.675593] Init: Power Port (0)
187 | [ 1.680489] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
188 | [ 1.688830] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
189 | [ 1.697611] usb usb1: Product: DWC OTG Controller
190 | [ 1.703805] usb usb1: Manufacturer: Linux 4.9.13-bee42-v8 dwc_otg_hcd
191 | [ 1.711787] usb usb1: SerialNumber: 3f980000.usb
192 | [ 1.718827] hub 1-0:1.0: USB hub found
193 | [ 1.724060] hub 1-0:1.0: 1 port detected
194 | [ 1.730839] usbcore: registered new interface driver usb-storage
195 | [ 1.738653] mousedev: PS/2 mouse device common for all mice
196 | [ 1.746937] bcm2835-wdt 3f100000.watchdog: Broadcom BCM2835 watchdog timer
197 | [ 1.755655] bcm2835-cpufreq: min=600000 max=1200000
198 | [ 1.762551] sdhci: Secure Digital Host Controller Interface driver
199 | [ 1.770269] sdhci: Copyright(c) Pierre Ossman
200 | [ 1.776641] sdhost: log_buf @ ffffff800811b000 (c7447000)
201 | [ 1.830029] mmc0: sdhost-bcm2835 loaded - DMA enabled (>1)
202 | [ 1.859487] mmc-bcm2835 3f300000.mmc: mmc_debug:0 mmc_debug2:0
203 | [ 1.867014] mmc-bcm2835 3f300000.mmc: DMA channel allocated
204 | [ 1.898170] sdhci-pltfm: SDHCI platform and OF driver helper
205 | [ 1.906804] ledtrig-cpu: registered to indicate activity on CPUs
206 | [ 1.914506] hidraw: raw HID events driver (C) Jiri Kosina
207 | [ 1.921676] usbcore: registered new interface driver usbhid
208 | [ 1.928801] usbhid: USB HID core driver
209 | [ 1.934435] Initializing XFRM netlink socket
210 | [ 1.940234] NET: Registered protocol family 17
211 | [ 1.941315] Indeed it is in host mode hprt0 = 00021501
212 | [ 1.952802] mmc0: host does not support reading read-only switch, assuming write-enable
213 | [ 1.952957] Key type dns_resolver registered
214 | [ 1.963780] Registered cp15_barrier emulation handler
215 | [ 1.963807] Registered setend emulation handler
216 | [ 1.964921] registered taskstats version 1
217 | [ 1.972958] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 72, base_baud = 0) is a PL011 rev2
218 | [ 1.973510] of_cfs_init
219 | [ 1.973712] of_cfs_init: OK
220 | [ 1.976953] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
221 | [ 1.983313] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
222 | [ 1.999764] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
223 | [ 2.028960] mmc1: queuing unknown CIS tuple 0x80 (7 bytes)
224 | [ 2.029346] Waiting for root device /dev/mmcblk0p2...
225 | [ 2.042281] mmc0: new high speed SDHC card at address aaaa
226 | [ 2.050102] mmcblk0: mmc0:aaaa SU16G 14.8 GiB
227 | [ 2.057653] mmcblk0: p1
228 | [ 2.069660] random: fast init done
229 | [ 2.105028] usb 1-1: new high-speed USB device number 2 using dwc_otg
230 | [ 2.113023] Indeed it is in host mode hprt0 = 00001101
231 | [ 2.132302] VFS: Cannot open root device "mmcblk0p2" or unknown-block(179,2): error -6
232 | [ 2.142782] Please append a correct "root=" boot option; here are the available partitions:
233 | [ 2.153872] 0100 4096 ram0 [ 2.157614] (driver?)
234 | [ 2.161381] 0101 4096 ram1 [ 2.165121] (driver?)
235 | [ 2.168816] 0102 4096 ram2 [ 2.172548] (driver?)
236 | [ 2.176165] 0103 4096 ram3 [ 2.179898] (driver?)
237 | [ 2.183500] 0104 4096 ram4 [ 2.187232] (driver?)
238 | [ 2.190834] 0105 4096 ram5 [ 2.194567] (driver?)
239 | [ 2.198135] 0106 4096 ram6 [ 2.201883] (driver?)
240 | [ 2.205474] 0107 4096 ram7 [ 2.209205] (driver?)
241 | [ 2.212793] 0108 4096 ram8 [ 2.216538] (driver?)
242 | [ 2.220130] 0109 4096 ram9 [ 2.223877] (driver?)
243 | [ 2.227446] 010a 4096 ram10 [ 2.231264] (driver?)
244 | [ 2.234793] 010b 4096 ram11 [ 2.238614] (driver?)
245 | [ 2.242099] 010c 4096 ram12 [ 2.245926] (driver?)
246 | [ 2.249406] 010d 4096 ram13 [ 2.253227] (driver?)
247 | [ 2.256667] 010e 4096 ram14 [ 2.260488] (driver?)
248 | [ 2.263872] 010f 4096 ram15 [ 2.267692] (driver?)
249 | [ 2.271042] b300 15558144 mmcblk0 [ 2.275044] driver: mmcblk
250 | [ 2.278801] b301 65536 mmcblk0p1 00000000-01[ 2.284164]
251 | [ 2.286557] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2)
252 | ```
253 |
254 | We can see the kernel is starting in 64bit mode using a `AArch64 Processor`
255 | ```
256 | [ 0.000000] Booting Linux on physical CPU 0x0
257 | [ 0.000000] Linux version 4.9.13-bee42-v8 (root@1aca9db9a114) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #1 SMP PREEMPT Wed Mar 1 17:38:31 UTC 2017
258 | [ 0.000000] Boot CPU: AArch64 Processor [410fd034]
259 | ```
260 |
261 | and is initializing all four available CPU cores
262 | ```
263 | [ 0.093043] Brought up 4 CPUs
264 | [ 0.093235] SMP: Total of 4 processors activated.
265 | ```
266 |
267 | but finally it ends up in a kernel panic because of the missing root filesystem.
268 | ```
269 | [ 2.029346] Waiting for root device /dev/mmcblk0p2...
270 | ...
271 | [ 2.132302] VFS: Cannot open root device "mmcblk0p2" or unknown-block(179,2): error -6
272 | ...
273 | [ 2.286557] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2)
274 | ```
275 |
276 | So, this was just for demonstrating the boot process until the Linux kernel will be loaded and started correctly.
277 |
278 |
279 | ## Building the Linux kernel
280 |
281 | But as you already guessed we have to build this 64bit Linux kernel first. And this will take some time to be explained and to run the kernel build itself.
282 |
283 | Luckily the Raspberry Pi Foundation provides a GitHub repo https://github.com/raspberrypi/linux with all the Linux kernel sources, and there is also a branch "rpi-4.9.y" which supports building a 64bit kernel. OK, this branch doesn't have a proper kernel configuration which is already optimized for Docker containers - but this part was just easy for me to fix.
284 |
285 | So I've already prepared a GitHub repo https://github.com/dieterreuter/rpi64-kernel to create a true 64bit Linux kernel for the Raspberry Pi 3. And of course with a Docker-optimized kernel configuration, where I have enable absolutely all necessary and important kernel modules and settings which helps to run Linux containers in an optimal way.
286 |
287 | The build process itself uses Docker Compose to build a Docker Image first with a complete build environment based upon Debian/Jessie. So you can see, this build always run in a well defined environment. It's running in an isolated Linux with Debian/Jessie inside of a Docker container. In this case we don't have to install anything (except Docker itself or on macOS Docker-for-Mac) on our host machine.
288 |
289 | As you can see, I'm using the command `docker-compose build` to build the Docker Image and later on I'm issuing a single build run with the command `docker-compose run builder`. And as a build parameter I can define a specific kernel default configuration file with `DEFCONFIG=docker_rpi3_defconfig`. That's all.
290 | ```
291 | $ cat build.sh
292 | #!/bin/bash
293 | set -e
294 |
295 | export DEFCONFIG=docker_rpi3_defconfig
296 | docker-compose build
297 | docker-compose run builder
298 | ```
299 |
300 | For easier usage I created a script "build.sh" with these commands, so we can just invoke a new build with a single command only.
301 | ```
302 | $ ./build.sh
303 | ```
304 |
305 | The build results can be found in a sub-folder `./builds/`, for each new build the script `build-kernel.sh` is creating a new build folder with an individual version based upon the date+time of the current build. So we can run subsequent builds and keep all the old build artefacts.
306 | ```
307 | $ tree builds
308 | builds
309 | └── 20170303-152804
310 | ├── 4.9.13-bee42-v8.config
311 | ├── 4.9.13-bee42-v8.tar.gz
312 | ├── 4.9.13-bee42-v8.tar.gz.sha256
313 | ├── bootfiles.tar.gz
314 | └── bootfiles.tar.gz.sha256
315 |
316 | 1 directory, 5 files
317 | ```
318 | ```
319 | $ ls -al ./builds/20170303-152804/
320 | -rw-r--r-- 1 dieter staff 140641 Mar 3 16:28 4.9.13-bee42-v8.config
321 | -rw-r--r-- 1 dieter staff 21863866 Mar 3 16:40 4.9.13-bee42-v8.tar.gz
322 | -rw-r--r-- 1 dieter staff 89 Mar 3 16:40 4.9.13-bee42-v8.tar.gz.sha256
323 | -rw-r--r-- 1 dieter staff 5092332 Mar 3 16:40 bootfiles.tar.gz
324 | -rw-r--r-- 1 dieter staff 83 Mar 3 16:40 bootfiles.tar.gz.sha256
325 | ```
326 |
327 | From the build script `build-kernel.sh` we'll get a couple of build artefacts. In "bootfiles.tar.gz" are all the files which have to be placed in the "/boot" folder on the FAT32 partition. These are namely the 64bit Linux kernel "kernel8.img", the device tree binary Linux kernel configuration file "bcm2710-rpi-3-b.dtb" and the kernel overlay files in a folder called "overlays/".
328 | ```
329 | $ tar vtf builds/20170303-152804/bootfiles.tar.gz
330 | -rw-r--r-- 0 root root 12704256 Mar 3 16:40 ./kernel8.img
331 | drwxr-xr-x 0 root root 0 Mar 3 16:40 ./overlays/
332 | ...
333 | -rw-r--r-- 0 root root 17714 Mar 3 16:40 ./bcm2710-rpi-3-b.dtb
334 | ```
335 |
336 | But more important is the file "4.9.13-bee42-v8.tar.gz". Here you'll find all kernel files we really need to install on "/boot" and in the root filesystem like "/lib/firmware" and the kernel modules "/lib/modules/4.9.13-bee42-v8/".
337 | ```
338 | $ tar vtf builds/20170303-152804/4.9.13-bee42-v8.tar.gz
339 | drwxr-xr-x 0 root root 0 Mar 3 16:40 ./lib/modules/4.9.13-bee42-v8/
340 | ...
341 | drwxr-xr-x 0 root root 0 Mar 3 16:40 ./lib/firmware/
342 | ...
343 | drwxr-xr-x 0 root root 0 Mar 3 16:40 ./boot/
344 | -rw-r--r-- 0 root root 12704256 Mar 3 16:40 ./boot/kernel8.img
345 | drwxr-xr-x 0 root root 0 Mar 3 16:40 ./boot/overlays/
346 | ...
347 | -rw-r--r-- 0 root root 17714 Mar 3 16:40 ./boot/bcm2710-rpi-3-b.dtb
348 | ```
349 |
350 | And if you're interested in the generated and used kernel configuration file, this can be found in "4.9.13-bee42-v8.config" as a build artefact.
351 |
352 |
353 | ### Create a Travis CI build job
354 |
355 | Most of the times it is easier and more reliable to use a CI (continous integration) system to run the build process on a cloud server, so I'm going to use [Travis CI](https://travis-ci.org).
356 |
357 | I just created the necessary Travis configuration file `.travis.yml` with some special settings.
358 | ```
359 | $ cat .travis.yml
360 | sudo: required
361 | services:
362 | - docker
363 | language: bash
364 | script:
365 | - ./travis-build.sh
366 | after_success:
367 | - ls -al builds/$BUILD_NR/*
368 | branches:
369 | only:
370 | - master
371 | except:
372 | - /^v\d.*$/
373 | ```
374 |
375 | With the help of an extra Travis build script `travis-build.sh` I'm now able to upload the build artefacts of every successful build as a new GitHub release at https://github.com/DieterReuter/rpi64-kernel/releases. This makes it very easy to consume these build artefacts later in another build process and I do have all the complete and detailed build logs available for future reference.
376 |
377 |
378 | ## Recap
379 |
380 | First we discussed how the Linux kernel will be used in the boot process and which necessary files we need to install on the "/boot" section of the FAT32 partiton on the SD card. Then we were able to boot a 64bit Linux kernel successfully on a Raspberry Pi 3 and seen the kernel boot logs appear on the serial UART console.
381 |
382 | With the help of a newly created GitHub repo we're now able to compile and package all necessary Linux kernel files in tarballs, so we could copy them over onto a SD card.
383 |
384 | From the boot attempt we know that the Linux kernel ends up in a "kernel panic", because we didn't provide a valid root filesystem on our SD card. So for the next part we'll covering how to create and use such a root filesystem
385 | in [Part 3 - Root filesystem](/part3-root-filesystem.md).
386 |
387 | --
388 |
389 | 
390 |
391 | --
392 | MIT License
393 |
394 | Copyright (c) 2017 Dieter Reuter
395 |
--------------------------------------------------------------------------------
/part3-root-filesystem.md:
--------------------------------------------------------------------------------
1 |
2 | # Part 3: Root Filesystem
3 |
4 | The root filesystem of a Linux operating system contains all the files you need to run Linux. It is typically placed on an extra partition and should generally be pretty small to keep the system fast and secure.
5 |
6 | At the [Hypriot project](https://blog.hypriot.com) we based HypriotOS on the Linux distro Debian/Jessie and we already built a complete set of root filesystems for different CPU architectures. One of the basic goals of HypriotOS is to keep the Linux system itself as small as possible - so we just added the basic packages to the rootfs and did some basic customization.
7 |
8 |
9 | ## Building a Root filesystem
10 |
11 | Normally one would use the Debian tool "debootstrap" to create a new root filesystem for Debian/Jessie and there are some detailed documentation about [Debootstrap](https://wiki.debian.org/Debootstrap). It will take some time to get familiar with this tools and after some time you can create your own customized rootfs from scratch as well.
12 |
13 | At Hypriot we did this work already and there is a complete GitHub repo to build all these root filesystems at https://github.com/hypriot/os-rootfs. We also provide ready-to-download tarballs at the [GitHub releases](https://github.com/hypriot/os-rootfs/releases) of this project.
14 |
15 | And luckily we do have a ready tarball for ARMv8/ARM64/AARCH64 for Debian/Jessie, so it's just easy to take this one for our workshop to build a 64bit Docker-enabled Linux operating system for the Raspberry Pi 3.
16 |
17 |
18 | ## Contents of a Root Filesystem
19 |
20 | So lets download the latest version of this rootfs of HypriotOS and analyze it.
21 | ```
22 | $ wget https://github.com/hypriot/os-rootfs/releases/download/v1.1.1/rootfs-arm64-debian-v1.1.1.tar.gz
23 | ```
24 |
25 | The first thing we could see, it is really small in size with 116 MBytes only.
26 | ```
27 | $ ls -alh rootfs-arm64-debian-v1.1.1.tar.gz
28 | -rw-r--r-- 1 dieter staff 116M Feb 27 17:05 rootfs-arm64-debian-v1.1.1.tar.gz
29 | ```
30 |
31 | But yes, believe me, there are all necessary Debian packages included to boot into a full Linux system.
32 | ```
33 | $ tar vtf rootfs-arm64-debian-v1.1.1.tar.gz | head -20
34 | drwxr-xr-x 0 root root 0 Feb 27 17:03 ./
35 | drwxr-xr-x 0 root root 0 Feb 27 17:04 ./sbin/
36 | lrwxrwxrwx 0 root root 0 Nov 8 2014 ./sbin/ip6tables -> xtables-multi
37 | -rwxr-xr-x 0 root root 14480 Nov 8 2014 ./sbin/ipmaddr
38 | lrwxrwxrwx 0 root root 0 Nov 8 2014 ./sbin/iptables-save -> xtables-multi
39 | -rwxr-xr-x 0 root root 74384 May 28 2016 ./sbin/dmsetup
40 | -rwxr-xr-x 0 root root 885 Feb 24 09:09 ./sbin/shadowconfig
41 | lrwxrwxrwx 0 root root 0 Sep 27 2014 ./sbin/modinfo -> /bin/kmod
42 | -rwxr-xr-x 0 root root 14504 Nov 13 16:15 ./sbin/pam_tally2
43 | -rwxr-xr-x 0 root root 10328 Mar 30 2015 ./sbin/fsfreeze
44 | -rwxr-xr-x 0 root root 102096 Dec 31 22:14 ./sbin/mke2fs
45 | -rwxr-xr-x 0 root root 6080 Apr 6 2015 ./sbin/fstab-decode
46 | lrwxrwxrwx 0 root root 0 Sep 27 2014 ./sbin/insmod -> /bin/kmod
47 | -rwxr-xr-x 0 root root 233968 Mar 30 2015 ./sbin/fdisk
48 | -rwxr-xr-x 0 root root 73088 Dec 31 22:14 ./sbin/tune2fs
49 | lrwxrwxrwx 0 root root 0 Jan 7 04:35 ./sbin/init -> /lib/systemd/systemd
50 | lrwxrwxrwx 0 root root 0 Sep 27 2014 ./sbin/rmmod -> /bin/kmod
51 | lrwxrwxrwx 0 root root 0 Dec 31 22:14 ./sbin/mkfs.ext2 -> mke2fs
52 | lrwxrwxrwx 0 root root 0 Sep 27 2014 ./sbin/depmod -> /bin/kmod
53 | -rwxr-xr-x 0 root root 27040 Mar 30 2015 ./sbin/blockdev
54 | ```
55 |
56 |
57 | ## Recap
58 |
59 | This part of the workshop was really easy because we already have a ready-to-use tarball with the latest version of a pre-configured Debian/Jessie-based HypriotOS for our 64bit Raspberry Pi 3.
60 |
61 | Lets sum up what components we do have now:
62 |
63 | 1. Bootloader - specific for the Raspberry Pi
64 | 2. Kernel - a Linux kernel in 64bit with the current LTS version 4.9.13 compiled and configured for the Raspberry Pi 3
65 | 3. Root Filesystem - from HypriotOS based on Debian/Jessie for AARCH64
66 |
67 | So, these are finally all the components we need to build our complete operating system. The final construction will be covered in [Part 4 - SD Card Image](/part4-sd-card-image.md) where we'll create a bootable SD card and assemble all of the components we've built so far.
68 |
69 | --
70 |
71 | 
72 |
73 | --
74 | MIT License
75 |
76 | Copyright (c) 2017 Dieter Reuter
77 |
--------------------------------------------------------------------------------
/part4-sd-card-image.md:
--------------------------------------------------------------------------------
1 |
2 | # Part 4: SD Card Image
3 |
4 | In the previous parts of our workshop to build a 64bit Docker OS for the Raspberry Pi 3 we're going through all the steps to create the basic building blocks and components we need:
5 |
6 | 1. [Bootloader](/part1-bootloader.md) - specific for the Raspberry Pi
7 | 2. [Kernel](/part2-kernel.md) - a Linux kernel in 64bit with the current LTS version 4.9.13 compiled and configured for the Raspberry Pi 3
8 | 3. [Root Filesystem](/part3-root-filesystem.md) - from HypriotOS based on Debian/Jessie for AARCH64
9 |
10 |
11 | ## TL;DR
12 |
13 | Here is the last repo to create the complete SD Card Image https://github.com/DieterReuter/image-builder-rpi64.
14 |
15 | You can download and flash the lastet of the SD Card Image from GitHub releases https://github.com/DieterReuter/image-builder-rpi64/releases/latest.
16 |
17 | * SD Image = hypriotos-rpi64-v20170303-185520.img.zip
18 | * Nodename = black-pearl
19 | * Username = pirate
20 | * Password = hypriot
21 |
22 |
23 | ## Final words...?
24 |
25 | I maybe will write some more details about the build process in a few days. But right now, feel free to use the final SD Card Image you can now download from the GitHub releases https://github.com/DieterReuter/image-builder-rpi64/releases/latest.
26 |
27 | --
28 |
29 | 
30 |
31 | --
32 | MIT License
33 |
34 | Copyright (c) 2017 Dieter Reuter
35 |
--------------------------------------------------------------------------------