Kernel.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <!doctype html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui">
  6. <title>Linux-Kurs - Kernel</title>
  7. <link type="text/css" rel="stylesheet" href="assets/css/github-markdown.css">
  8. <link type="text/css" rel="stylesheet" href="assets/css/pilcrow.css">
  9. <link rel="shortcut icon" href="assets/favicon.ico">
  10. </head>
  11. <body>
  12. <article class="markdown-body"><h1 id="linux-kurs---kernel"><a class="header-link" href="#linux-kurs---kernel"></a>Linux-Kurs - Kernel</h1>
  13. <p><a href="https://linuxkurs.ch">https://linuxkurs.ch</a></p>
  14. <p>Wahlweise konntest Du dein System auf Slackware -current aktualisieren oder die stabile Version beibehalten. Nun ist es an der Zeit, dass wir uns das Herzstück deines Linux-Systems etwas genauer anschauen, dem Kernel.</p>
  15. <p><strong>Hinweis</strong>: Sofern nicht anders erwähnt, müssen alle folgenden Kommandos mit Root-Rechten ausgeführt werden.</p>
  16. <h2 id="initrd"><a class="header-link" href="#initrd"></a>initrd</h2>
  17. <p>Bisher verwenden wir den monolithischen <em>huge</em> Kernel. Dabei handelt es sich um eine grosse Datei, die alle wichtigen Treiber bereits enthält. Eine Alternative ist die Nutzung des sogenannten <em>generic</em> Kernels. Dieser enthält im Kernel-Image nur einen Bruchteil der Treiber. Um das System dennoch erfolgreich starten zu können, benötigst Du zusätzlich eine sogenannte <em>initrd</em>, was für <em>initial ramdisk</em> steht.</p>
  18. <p>Diese initrd ist dynamisch und wird auf dein System angepasst. Beim Startvorgang lädt der Kernel die initrd nach und fährt dann mit dem init Prozess fort.</p>
  19. <p>Slackware enthält ein Script mit dem Namen <em>mkinitrd_command_generator.sh</em>, welches dich bei der Erstellung der initrd unterstützt. Es überprüft welche Kernel-Module auf deinem System benötigt werden und gibt dir einen Befehl aus der zur Erstellung der Ramdisk ausgeführt werden kann:</p>
  20. <p><code>/usr/share/mkinitrd/mkinitrd_command_generator.sh</code></p>
  21. <p class="img-container"><img src="./slackware_mkinitrd.png" alt=""></p>
  22. <p>Ohne weitere Parameter bezieht sich das Script auf den aktuell laufenden Kernel. Es wird standardmässig keine Ramdisk erstellt sondern nur der Befehl ausgegeben, mit dem diese generiert werden kann.</p>
  23. <p>Markiere und kopiere die letzte Zeile und füge Sie in der Shell ein. Mit Enter kannst Du den Befehl auslösen. Dadurch wird eine Ramdisk im Verzeichnis /boot mit dem Namen initrd.gz erstellt.</p>
  24. <p>Um den Kernel mit dieser initrd zu starten, müssen entsprechende Einträge in der Bootloader-Konfiguration hinterlegt werden. </p>
  25. <div style="page-break-after: always;"></div>
  26. <p>Füge dazu folgende Zeilen am Ende der <em>/etc/lilo.conf</em> vor dem Hinweis <em># Linux bootable partition config ends</em> hinzu:</p>
  27. <pre class="hljs"><code>image = /boot/vmlinuz-<span class="hljs-keyword">generic</span>
  28. initrd = /boot/initrd.gz
  29. root = /dev/sda2
  30. <span class="hljs-keyword">label</span> = Linux-<span class="hljs-keyword">Generic</span>
  31. <span class="hljs-keyword">read</span>-only
  32. </code></pre><p>Führe <code>lilo</code> aus und versuche die Kernel-Versionen mit der Ramdisk zu starten. Der Startvorgang sollte ein wenig schneller gehen als mit dem <em>huge</em> Kernel.</p>
  33. <p>Die initrd muss nach jedem Kernel-Update neu erstellt werden und der Bootloader lilo muss ausgeführt werden damit die Änderungen aktiv werden. Um diesen Prozess zu vereinfachen hat der Slackware-Benutzer <em>zerouno</em> ein Script erstellt, welches nach einem Kernel-Upgrade mittels slackpkg die Möglichkeit bietet die initrd neu zu erstellen und lilo auszuführen. Du kannst es wie folgt herunterladen und aktivieren:</p>
  34. <pre class="hljs"><code>wget <span class="hljs-symbol">https:</span>/<span class="hljs-regexp">/linuxkurs.ch/kurs</span><span class="hljs-regexp">/zlookkernel.sh -O /usr</span><span class="hljs-regexp">/libexec/slackpkg</span><span class="hljs-regexp">/functions.d/zlookkernel</span>.sh
  35. chmod +x /usr/libexec/slackpkg/functions.d/zlookkernel.sh</code></pre><p>Beim nächsten Kernel-Update mittels slackpkg wirst Du abschliessend gefragt ob die initrd neu erstellt werden soll und lilo ausgeführt werden soll. Sofern Du dies mit <strong>Y</strong> beantwortest erfolgt der Prozess automatisch.</p>
  36. <h2 id="eigenen-kernel-erstellen"><a class="header-link" href="#eigenen-kernel-erstellen"></a>Eigenen Kernel erstellen</h2>
  37. <p>Wir konnten die Kernel Varianten <em>huge</em> und <em>generic</em> der Distribution kennenlernen. Es kann allerdings vorkommen, dass eine neuere Kernelversion benötigt wird. Grund dafür kann zum Beispiel fehlende Hardwareunterstützung in der Distributions-Version sein. In solchen Fällen kann es sinnvoll sein einen einen eigenen Kernel zu compilieren.</p>
  38. <p>Wir gehen davon aus das Du den <em>generic</em> Kernel gestartet hast. Sollte dies nicht der Fall sein, starte dein System neu und wähle im lilo Bootmenü den Punkt: <em>Linux-Generic</em>.</p>
  39. <p>Um einen eigenen Kernel compilieren zu können, benötigen wir die entsprechenden Quellen. Die offiziellen Kernel-Quellen findest du auf: <a href="https://www.kernel.org">https://www.kernel.org</a></p>
  40. <p>Kopiere dir beispielsweise im Firefox den Link auf die aktuelle stabile Kernelversion indem du mit der rechten Maustaste auf <em>[tarball]</em> klickst und <strong>Link-Adresse kopieren</strong> wählst. Öffne daraufhin ein Terminal und wechsle in das Verzeichnis <em>/usr/src</em> in dem sich üblicherweise die Kernel-Quellen befinden:</p>
  41. <p><code>cd /usr/src</code></p>
  42. <p>Mit Hilfe des <strong>wget</strong> Befehls kannst Du das Kernel-Archiv herunterladen. Gebe dazu <code>wget</code> gefolgt von einem Leerzeichen ein und füge den zuvor kopierten Link mit <code>Ctrl + Shift + V</code> ein.</p>
  43. <p>Zum Beispiel:</p>
  44. <p><code>wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.1.tar.xz</code></p>
  45. <div style="page-break-after: always;"></div>
  46. <p>Entpacken kannst Du das Archiv mit folgendem Kommando:</p>
  47. <p><code>tar -xvpf linux-5.4.1.tar.xz</code></p>
  48. <p>Passe dabei den Dateinamen entsprechend an und wechsle daraufhin in den neu erstellten Pfad, in unserem Beispiel mit Hilfe von:</p>
  49. <p><code>cd linux-5.4.1</code></p>
  50. <p>Als Basis für den neuen Kernel kannst Du die Konfiguration des aktiven <em>Generic</em> Kernels verwenden. Mit folgendem Befehl kannst Du die bisherige Konfiguration übernehmen:</p>
  51. <p><code>zcat /proc/config.gz &gt; .config</code></p>
  52. <p>Der Befehl <code>zcat</code> verhält sich ähnlich wie der bereits bekannte <code>cat</code> Befehl, ermöglicht aber auch das Anzeigen von gzip-komprimierten Dateien. Das <code>&gt;</code> Zeichen leitet die Ausgabe um, in diesem Falle in die Datei <em>.config</em> im aktuellen Verzeichnis.</p>
  53. <p>Mit Hilfe von <code>make olddefconfig</code> kann daraufhin die alte Konfiguration adaptiert werden:</p>
  54. <p><code>make olddefconfig</code></p>
  55. <p>Nun ist es möglich Anpassungen an der Kernelkonfiguration vorzunehmen. Dabei hilft dir der Befehl <code>make menuconfig</code>. Alternativ gibt es eine grafische Konfigurationsoberfläche die Du mit <code>make xconfig</code> aufrufen kannst.</p>
  56. <p>Anpassungen am Kernel sind optional. Als Beispiel möchten wir die Unterstützung für das Sicherheitsframework AppArmor aktivieren. Dieses bietet zusätzlichen Schutz auch vor noch nicht öffentlich bekannten Sicherheitslücken, sogenannten Zero-Day-Exploits.</p>
  57. <p>Starte im Verzeichnis in dem sich die Kernel-Sourcen befinden den folgenden Befehl:</p>
  58. <p><code>make menuconfig</code></p>
  59. <p>Es begrüsst dich eine TUI-Oberfläche in der Du wie gewohnt navigieren kannst. Wenn Du ein Untermenü öffnest, kannst Du über den <strong>Exit</strong> Befehl eine Ebene zurückspringen. </p>
  60. <p><strong>Hinweis:</strong> Im Hauptmenü beendet <strong>Exit</strong> die Anwendung.</p>
  61. <div style="page-break-after: always;"></div>
  62. <p>Navigiere mit den Cursortasten oder durch Aufruf des Kurzbefehls zum Punkt <em>Security Options</em> und öffne das Untermenü durch Eingabe von Enter, sofern der Punkt <strong>Select</strong> aktiviert ist.</p>
  63. <p class="img-container"><img src="./slackware_kernel_security_options.png" alt=""></p>
  64. <p>Scrolle in der sich öffnenden Parameterliste bis zu den Punkt AppArmor Support und aktiviere diesen mit der Space-Taste.</p>
  65. <p class="img-container"><img src="./slackware_kernel_apparmor.png" alt=""></p>
  66. <p>Des weiteren muss das AppArmor <em>lockdown</em> Modul zur Liste der <em>LSMs</em> (Linux Security Modules) hinzugefügt werden. Wähle dazu weiter unten den Punkt <strong>Ordered list of enabled LMSs</strong> aus:</p>
  67. <p class="img-container"><img src="./slackware_kernel_lockdown.png" alt=""></p>
  68. <p>Es öffnet sich eine Liste der aktivierten Security Module. Füge dort <strong>,apparmor</strong> hinzu:</p>
  69. <p class="img-container"><img src="./slackware_kernel_lockdown_list.png" alt=""></p>
  70. <p>Du kannst bei Bedarf weiter Änderungen vornehmen. Speichere deine Änderungen ab, indem Du mit der Tab-Taste den Punkt <strong>Save</strong> anwählst und mit Enter bestätigst.</p>
  71. <p>Du wirst nach einem Dateinamen für die Kernel-Konfigurationsdatei gefragt. Standardmässig lautet dieser <em>.config</em>. Wir gehen davon aus, dass Du die Einstellung unverändert beibehältst.</p>
  72. <p>Als nächstes kannst Du die Anwendung mit Hilfe des <strong>Exit</strong> Befehls beenden. Du musst ihn möglicherweise mehrmals anwählen, falls Du dich in einem Untermenü befindest.</p>
  73. <p>Mit folgendem Befehl startest Du den Compiliervorgang:</p>
  74. <p><code>make bzImage modules</code></p>
  75. <p>Es werden das Kernel-Image (<em>bzImage</em>) sowie die Kernelmodule (<em>modules</em>) compiliert. Dieser Vorgang kann einige Zeit in Anspruch nehmen. Du kannst den Compiliervorgang beschleunigen indem du den make-Parameter <code>-j</code> gefolgt von der Anzahl der CPU-Kerne deines Computers angibst.</p>
  76. <p>Bei vier CPU-Kernen wäre dies:</p>
  77. <p><code>make -j 4 bzImage modules</code></p>
  78. <p>Um die Anzahl der CPU-Kerne zu ermitteln, kannst Du den Konsolenbefehl <code>nproc</code> nutzen.</p>
  79. <p>Die compilierten Kernelmodule müssen daraufhin in den entsprechenden Pfad kopiert werden. Standardmässig wäre dies <em>/lib/modules/</em> gefolgt von der Kernelversion. Dabei hilft dir das folgende Kommando:</p>
  80. <p><code>make modules_install</code></p>
  81. <p>Der Befehl kopiert nicht nur die Kernelmodule an den richtigen Ort sondern führt abschliessend auch das <code>depmod</code> Kommando aus. Einige Kernelmodule haben Abhängigkeiten, die mit Hilfe von <strong>depmod</strong> aufgelöst und in der Datei <em>/lib/modules/KERNELVERSION/modules.dep</em> hinterlegt werden.</p>
  82. <div style="page-break-after: always;"></div>
  83. <p>Das erstellte Kernel-Image muss nun in den <em>/boot</em> Pfad kopiert werden:</p>
  84. <p><code>cp arch/x86/boot/bzImage /boot/vmlinuz-5.4.1</code></p>
  85. <p>Ersetze die Kernel-Version (in diesem Beispiel <em>5.4.1</em>) durch diejenige des Kernels den Du compiliert hast.</p>
  86. <p>Es ist sinnvoll auch die <em>System.map</em> sowie die Kernel-Konfiguration in den <em>/boot</em> Pfad zu kopieren:</p>
  87. <pre class="hljs"><code>cp System<span class="hljs-selector-class">.map</span> /boot/System<span class="hljs-selector-class">.map-5</span>.<span class="hljs-number">4.1</span>
  88. cp <span class="hljs-selector-class">.config</span> /boot/config-<span class="hljs-number">5.4</span>.<span class="hljs-number">1</span></code></pre><p>Auch hier muss der Dateiname entsprechend angepasst werden, so dass er der compilierten Kernelversion entspricht. Die <em>System.map</em> wird im Fehlerfalle zum Debugging genutzt. Ausführliche Informationen dazu findest du auf folgender Webseite: <a href="https://rlworkman.net/system.map/">https://rlworkman.net/system.map/</a></p>
  89. <h3 id="ramdisk"><a class="header-link" href="#ramdisk"></a>Ramdisk</h3>
  90. <p>Da wir den neuen Kernel auf der Basis des <em>generic</em> Kernels erstellt haben, ist eine Ramdisk zwingend notwendig. Zur Erstellung kannst Du das <em>mkinitrd_command_generator.sh</em> Script zur Hilfe nehmen.</p>
  91. <p><code>$(/usr/share/mkinitrd/mkinitrd_command_generator.sh -k 5.4.1 -a &quot;-o /boot/initrd-5.4.1.gz&quot; --run)</code></p>
  92. <p>Ersetze hierbei die Kernelversion durch die deines Kernels. Der Parameter <em>--run</em> gibt nur das Kommando zur Erstellung der initrd ohne weitere Bemerkungen aus. Da wir die gesamte Zeichenkette in <em>$()</em> stellen, wird diese von der BASH als Befehl interpretiert, also direkt ausgeführt und die initrd erzeugt. </p>
  93. <p>Jedes Mal wenn Du einen neuen Kernel compilierst und verwenden möchtest musst Du initrd erneut erzeugen.</p>
  94. <h3 id="bootloader"><a class="header-link" href="#bootloader"></a>Bootloader</h3>
  95. <p>Abschliessend wird der Bootloader angepasst, so dass Du in der Lage bist deinen neuen Kernel zu starten.</p>
  96. <p>Füge dazu einen entsprechenden Eintrag vor dem Hinweis <em># Linux bootable partition config ends</em> zu der <em>/etc/lilo.conf</em> Konfigurationsdatei hinzu:</p>
  97. <pre class="hljs"><code>image = /boot/vmlinuz<span class="hljs-number">-5.4</span><span class="hljs-number">.1</span>
  98. initrd = /boot/initrd<span class="hljs-number">-5.4</span><span class="hljs-number">.1</span>.gz
  99. root = /dev/sda2
  100. label = Linux<span class="hljs-number">-5.4</span><span class="hljs-number">.1</span>
  101. read-only</code></pre><p>Wobei die Versionsnummer entsprechend angepasst werden muss, so dass sie deinem Kernel entspricht.</p>
  102. <p>Führe <code>lilo</code> aus und versuche deine erste selbstcompilierte Kernel-Versionen zu starten.</p>
  103. <div style="page-break-after: always;"></div>
  104. <h2 id="apparmor"><a class="header-link" href="#apparmor"></a>AppArmor</h2>
  105. <p>Wir haben den Kernel nun um AppArmor-Unterstützung erweitert. Nun fehlt nur noch die passende Anwendung. Diese lässt sich mit Hilfe des SlackBuild-Scriptes erstellen:</p>
  106. <p><code>sbopkg -i apparmor</code></p>
  107. <p>Damit AppArmor beim Systemstart automatisch geladen wird, kann ein entsprechender Eintrag zur Datei <em>/etc/rc.d/rc.local</em> hinzugefügt werden:</p>
  108. <p><code>vi /etc/rc.d/rc.local</code></p>
  109. <pre class="hljs"><code><span class="hljs-comment"># Start apparmor</span>
  110. <span class="hljs-keyword">if</span> [ -x /etc/rc.d/rc.apparmor ]; <span class="hljs-keyword">then</span>
  111. /etc/rc.d/rc.apparmor start
  112. <span class="hljs-keyword">fi</span></code></pre><p>Starte dein System neu und untersuche ob AppArmor aktiv ist:</p>
  113. <p><code>aa-status</code></p>
  114. <p>Damit hast du erfolgreich deinen eigenen Kernel compiliert.</p>
  115. <hr>
  116. <p>© Lioh Moeller</p>
  117. </article>
  118. </body>
  119. </html>