Differences

This shows you the differences between two versions of the page.

Link to this comparison view

isc:labs:kernel:tasks:01 [2021/11/25 13:25]
radu.mantu
isc:labs:kernel:tasks:01 [2021/12/02 14:09] (current)
radu.mantu
Line 1: Line 1:
 ==== 01. [??p] Prerequisites ==== ==== 01. [??p] Prerequisites ====
  
-=== [??p] Task A - Dependencies ​installation ​===+=== [??p] Task A - Dependencies ===
  
-<note important+Before we get down to it, there are a few packages that need to be installed. The following commands //should// work on Ubuntu 20.04 Desktop. While most of these probably came with the base system, we'll enumerate them here for the sake of completeness. If you're using other desktop environments,​ most of these should have a correspondent (probably with an identical name). 
-TODOUbuntu + 
-</note>+<code bash
 +[student@host]$ sudo apt update 
 +[student@host]$ sudo apt install curl make gcc git iptables dnsutils qemu-system debootstrap libxtables-dev 
 +</​code>​ 
 + 
 +In case you're wandering what any of these are: 
 +  * ''​curl'':​ CLI tool for fetching (HTTP) data from servers 
 +  * ''​make'':​ project build automation tool 
 +  * ''​gcc'':​ GNU C compiler 
 +  * ''​git'':​ CLI tool for content tracking & versioning 
 +  * ''​iptables'':​ user space interface to the kernel'​s packet filter 
 +  * ''​dnsutils'':​ contains **dig** which we'll need to send out DNS queries 
 +  * ''​qemu-system'':​ PC system emulator; if you don't have space for all off them, install only **qemu-system-x86** or **-arm** 
 +  * ''​debootstrap'':​ user space environment bootstrapping tool 
 +  * ''​libxtables-dev'':​ development files for the packet filtering framework; needed for //"​xtables.h"//​ 
 + 
 +Moving forward, we prepared a code skeleton for you: {{:​isc:​labs:​kernel:​tasks:​skeleton.zip|}}. It's structure is as follows: 
 + 
 +<code bash> 
 +[student@host]$ tree -L 2 skeleton  
 +skeleton                    --root of workspace 
 +├── 02/                        --> task 2: basically a "Hello World"​ 
 +│   ├── Kbuild 
 +│   ├── Makefile 
 +│   ├── my_first_module.c 
 +│   └── patches/ 
 +├── 03/                        --> task 3: an iptables extension 
 +│   ├── include/ 
 +│   ├── module/ 
 +│   └── plugin/ 
 +└── images/ ​                   --> task 1: VM hard disk images (empty) 
 + 
 +7 directories,​ 3 files 
 +</​code>​ 
 + 
 +At this time, there'​s no point in taking a more detailed look at each file. In stead, let us focus on the task at hand and prepare our testing environment.
  
 === [??p] Task B - Development environment === === [??p] Task B - Development environment ===
  
-When developing new features for the kernel, chances are that you will screw up. Often. Depending on the severity, the kernel may or may not recover. So to avoid restarting your PC over and over, it's better to work in a minimal virtualized environment. As such, we will first bootstrap a loopback disk image with a basic Ubuntu system, but without the kernel. Eventually, we will boot a virtual ​macine ​with **qemu-system-x86_64** from this disk image, with a custom kernel that we will build ourselves.+When developing new features for the kernel, chances are that you will screw up. Often. Depending on the severity, the kernel may or may not recover. So to avoid restarting your PC over and over, it's better to work in a minimal virtualized environment. As such, we will first bootstrap a loopback disk image with a basic Ubuntu system, but without the kernel. Eventually, we will boot a virtual ​machine ​with **qemu-system-x86_64** from this disk image, with a custom kernel that we will build ourselves.
  
 <​note>​ <​note>​
Line 30: Line 65:
  
 # bootstrat the Ubuntu system # bootstrat the Ubuntu system
-[student@host]$ sudo debootstrap --arch amd64 focal /mnt https://mirrors.kernel.org/ubuntu+[student@host]$ sudo debootstrap --arch amd64 focal /mnt http://archive.ubuntu.com/ubuntu
 </​code>​ </​code>​
  
Line 44: Line 79:
 Retype new password: root Retype new password: root
 passwd: password updated successfully passwd: password updated successfully
 +
 +# while we're here, set Google DNS as primary DNS
 +# qemu has a bug where it refuses to fall back to other resolvers
 +# so it will be hard stuck on 127.0.0.53 ==> can't resolve domain names
 +[   ​root@jail]$ echo '​nameserver 8.8.8.8'​ > /​etc/​resolv.conf
  
 # exit from this bash instance and escape from the chroot jail # exit from this bash instance and escape from the chroot jail
Line 74: Line 114:
  
 # compile the kernel using all cores # compile the kernel using all cores
-[student@host]$ make -j $(nproc) ​bzImage +[student@host]$ make -j $(nproc)
- +
-# required for building out-of-tree modules -- see warning below +
-[student@host]$ make modules_prepare ​+
  
 # return to the previous direcotry # return to the previous direcotry
Line 85: Line 122:
 [[https://​ocw.cs.pub.ro/​courses/​_media/​isc/​labs/​kernel/​tasks/​menuconfig-demo.gif|{{ :​isc:​labs:​kernel:​tasks:​menuconfig-demo.gif?​700 |}}]] [[https://​ocw.cs.pub.ro/​courses/​_media/​isc/​labs/​kernel/​tasks/​menuconfig-demo.gif|{{ :​isc:​labs:​kernel:​tasks:​menuconfig-demo.gif?​700 |}}]]
 <​html><​center><​i>​ Click GIF to maximize. </​i></​center></​html>​ <​html><​center><​i>​ Click GIF to maximize. </​i></​center></​html>​
- 
-<note important>​ 
-In kernel 5.10.x, a new feature was introduced. This feature crashed many build environments and if you follow older kernel development tutorials, you may encounter such an error when building out-of-tree kernel modules (which we'll also do later on): 
- 
-<​code>​ 
-make[3]: *** No rule to make target '​scripts/​module.lds',​ needed by '​...'​. ​  Stop. 
-make[2]: *** [scripts/​Makefile.modpost:​140:​ __modpost] Error 2 
-make[1]: *** [Makefile:​1761:​ modules] Error 2 
-</​code>​ 
- 
-The problem here is that a linker script is missing. [[https://​wiki.osdev.org/​Linker_Scripts|Linker scripts]] are used by **ld** when combining object files into the final executable. Without it, the linker doesn'​t know where to place each section in the output binary. If the user does not supply one, **ld** uses a built-in script. Normally, this default script does its job well. So much so that most programmers never learn of its existence. The kernel, however, is a different kind of beast and needs some fine tuning during compilation. Before 5.10.x, there was a //​module-common.lds//​ script that was used for module compilation. After 5.10.x, someone considered it a good idea to replace it with //​module.lds.S//,​ which requires a bit of processing before obtaining //​module.lds//​. Hence why we run ''​$ make modules_prepare ''​. 
-</​note>​ 
  
 === Booting up the virtual machine === === Booting up the virtual machine ===
Line 103: Line 128:
  
 <code bash> <code bash>
-$ sudo qemu-system-x86_64 ​                           \ +[student@host]$ sudo qemu-system-x86_64 ​                           \ 
-    -m 4G                                            \ +                  -m 4G                                            \ 
-    -smp 1                                           \ +                  -smp 1                                           \ 
-    -enable-kvm ​                                     \ +                  -enable-kvm ​                                     \ 
-    -kernel linux/​arch/​x86/​boot/​bzImage ​             \ +                  -kernel linux/​arch/​x86/​boot/​bzImage ​             \ 
-    -drive file=images/​ubuntu.raw,​format=raw,​index=0 \ +                  -drive file=images/​ubuntu.raw,​format=raw,​index=0 \ 
-    -append '​root=/​dev/​sda rw console=ttyS0 nokaslr'​ \ +                  -append '​root=/​dev/​sda rw console=ttyS0 nokaslr'​ \ 
-    -nographic+                  -nographic
 </​code>​ </​code>​
  
Line 128: Line 153:
 </​note>​ </​note>​
  
-After starting the VM and logging in as //root// (with the password set earlier), try finding out the kernel version in both the host and guest operating systems:+After starting the VM and logging in as //root// (with the password ​that was set earlier), try finding out the kernel version in both the host and guest operating systems:
  
 <code bash> <code bash>
Line 152: Line 177:
 # list available interfaces (in a colorful fashion) # list available interfaces (in a colorful fashion)
 [root@guest]$ ip -c addr show [root@guest]$ ip -c addr show
 +1: lo: <​LOOPBACK,​UP,​LOWER_UP>​ mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 +    link/​loopback 00:​00:​00:​00:​00:​00 brd 00:​00:​00:​00:​00:​00
 +    inet 127.0.0.1/8 scope host lo
 +       ​valid_lft forever preferred_lft forever
 +    inet6 ::1/128 scope host 
 +       ​valid_lft forever preferred_lft forever
 +2: enp0s3: <​BROADCAST,​MULTICAST>​ mtu 1500 qdisc noop state DOWN group default qlen 1000
 +    link/ether 52:​54:​00:​12:​34:​56 brd ff:​ff:​ff:​ff:​ff:​ff
 +3: sit0@NONE: <​NOARP>​ mtu 1480 qdisc noop state DOWN group default qlen 1000
 +    link/sit 0.0.0.0 brd 0.0.0.0
 +
 +# send a DHCP request on your Ethernet interface
 +[root@guest]$ dhclient enp0s3
  
-send a DHCP request on your eth interface +check if an IP address was allocated 
-[root@guest]$ ​dhclient eth0+[root@guest]$ ​ip -c addr show enp0s3 
 +2: enp0s3: <​BROADCAST,​MULTICAST,​UP,​LOWER_UP>​ mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 
 +    link/ether 52:​54:​00:​12:​34:​56 brd ff:​ff:​ff:​ff:​ff:​ff 
 +    inet 10.0.2.15/​24 brd 10.0.2.255 scope global dynamic enp0s3 
 +       ​valid_lft 86313sec preferred_lft 86313sec 
 +    inet6 fec0::​5054:​ff:​fe12:​3456/​64 scope site dynamic mngtmpaddr  
 +       ​valid_lft 86318sec preferred_lft 14318sec 
 +    inet6 fe80::​5054:​ff:​fe12:​3456/​64 scope link  
 +       ​valid_lft forever preferred_lft forever
 </​code>​ </​code>​
 </​note>​ </​note>​
isc/labs/kernel/tasks/01.1637839514.txt.gz · Last modified: 2021/11/25 13:25 by radu.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0