**TODO** +editPic: Linux Kernel Developer -> (Ring Layer 0)
+addSection: Kernel Virtualization Engine
KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.
Empfohlene Bücher für Nichtinitialisiertevoid *i
"Die Menschen verstehen Bücher erst, wenn sie eine gewisse Lebensspanne erreicht haben, oder jedenfalls, wenn niemand ein tiefes Buch versteht, bis er zumindest einen Teil seines Inhalts gesehen und gelebt hat." –Ezra Pfund
Eine Reise von tausend Codemeilen muss mit einem einzigen Schritt beginnen. Wenn Sie sich nicht sicher sind, mit welchem der folgenden Bücher Sie beginnen sollen, machen Sie sich keine Sorgen, und wählen Sie eines Ihrer Bücher aus. Nicht alle, die wandern, sind verloren. Da alle Straßen letztendlich mit der Autobahn verbunden sind , werden Sie neue Dinge auf Ihrer Kernel-Reise erkunden, während die Seiten fortschreiten, ohne auf Sackgassen zu stoßen, und sich letztendlich mit der Autobahn verbinden code-set
. Lesen Sie aufmerksam und denken Sie daran: Code ist keine Literatur .
Was übrig bleibt, ist kein Ding oder eine Emotion oder ein Bild oder ein mentales Bild oder eine Erinnerung oder gar eine Idee. Es ist eine Funktion. Eine Art Prozess. Ein Aspekt des Lebens, der als Funktion von etwas "Größerem" beschrieben werden könnte. Und deshalb scheint es nicht wirklich "getrennt" von dem Anderen zu sein. Wie die Funktion eines Messers - etwas zu schneiden - ist in der Tat nicht vom Messer selbst getrennt. Die Funktion wird momentan möglicherweise nicht verwendet, ist jedoch möglicherweise NIEMALS separat.
Solovay Strassen Derandomisierter Algorithmus für den Primalitätstest :
Lesen Sie, um nicht zu widersprechen und zu verwechseln. noch zu glauben und für selbstverständlich zu halten; noch zu reden und Diskurs zu finden; aber zu wiegen und zu überlegen. Einige Bücher sollen verkostet werden, andere sollen geschluckt werden, und einige wenige sollen gekaut und verdaut werden: das heißt, einige Bücher sollen nur in Teilen gelesen werden, andere sollen gelesen werden, aber nicht neugierig, und einige sollen vollständig gelesen werden und mit Fleiß und Aufmerksamkeit.
static void tasklet_hi_action(struct softirq_action *a)
{
struct tasklet_struct *list;
local_irq_disable();
list = __this_cpu_read(tasklet_hi_vec.head);
__this_cpu_write(tasklet_hi_vec.head, NULL);
__this_cpu_write(tasklet_hi_vec.tail, this_cpu_ptr(&tasklet_hi_vec.head));
local_irq_enable();
while (list) {
struct tasklet_struct *t = list;
list = list->next;
if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED,
&t->state))
BUG();
t->func(t->data);
tasklet_unlock(t);
continue;
}
tasklet_unlock(t);
}
local_irq_disable();
t->next = NULL;
*__this_cpu_read(tasklet_hi_vec.tail) = t;
__this_cpu_write(tasklet_hi_vec.tail, &(t->next));
__raise_softirq_irqoff(HI_SOFTIRQ);
local_irq_enable();
}
}
Kern-Linux (5 -> 1 -> 3 -> 2 -> 7 -> 4 -> 6)
„Die Natur hat weder Kern noch Schale. sie ist alles auf einmal “- Johann Wolfgang von Goethe
Der Leser sollte mit Betriebssystemkonzepten vertraut sein . ein faires Verständnis für lang laufende Prozesse und deren Unterschiede zu Prozessen mit kurzen Ausführungsspitzen; Fehlertoleranz bei gleichzeitiger Einhaltung von weichen und harten Echtzeitbeschränkungen. Während des Lesens ist es wichtig, n/ack
die von der Linux-Kernelquelle in den Kernsubsystemen getroffenen Entwurfsentscheidungen zu verstehen und zu verstehen .
Threads [und] Signale [sind] eine plattformabhängige Spur von Elend, Verzweiflung, Entsetzen und Wahnsinn (~ Anthony Baxte). Davon abgesehen sollten Sie ein selbstbewertender C-Experte sein, bevor Sie in den Kernel eintauchen. Sie sollten auch gute Erfahrungen mit verknüpften Listen, Stapeln, Warteschlangen, Rot-Schwarz-Bäumen, Hash-Funktionen usw. haben.
volatile int i;
int main(void)
{
int c;
for (i=0; i<3; i++) {
c = i&&&i;
printf("%d\n", c); /* find c */
}
return 0;
}
Die Schönheit und Kunst der Linux-Kernel-Quelle liegt in der absichtlichen Code-Verschleierung. Dies ist häufig erforderlich, um die Bedeutung von zwei oder mehr Operationen auf saubere und elegante Weise zu vermitteln. Dies gilt insbesondere beim Schreiben von Code für Mehrkernarchitekturen.
Videovorträge zu Echtzeitsystemen , Aufgabenplanung , Speicherkomprimierung , Speichersperren , SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
- Linux-Kernel-Entwicklung - Robert Love
- Den Linux-Kernel verstehen - Daniel P. Bovet, Marco Cesati
- Die Kunst von Linux KerneL Design - Yang Lixiang
- Professionelle Linux Kernel Architektur - Wolfgang Mauerer
- Design des UNIX-Betriebssystems - Maurice J. Bach
- Den Linux Virtual Memory Manager verstehen - Mel Gorman
- Linux Kernel Internals - Tigran Aivazian
- Embedded Linux Primer - Christopher Hallinan
Linux-Gerätetreiber (1 -> 2 -> 4 -> 3 -> 8 -> ...)
"Musik trägt dich nicht mit. Du musst sie strikt mitnehmen, weil du dich wirklich nur auf diesen kleinen Kern aus Emotionen oder Geschichten konzentrieren kannst." - Debbie Harry
Ihre Aufgabe besteht im Wesentlichen darin, eine Hochgeschwindigkeitskommunikationsschnittstelle zwischen dem Hardwaregerät und dem Softwarekernel einzurichten. Sie sollten das Hardware-Referenzdatenblatt / -Handbuch lesen, um das Verhalten des Geräts und dessen Steuerungs- und Datenzustände sowie die bereitgestellten physischen Kanäle zu verstehen. Assembler-Kenntnisse für Ihre spezielle Architektur und gute Kenntnisse der VLSI-Hardwarebeschreibung Sprachen wie VHDL oder Verilog helfen Ihnen auf lange Sicht.
F : Aber warum muss ich die Hardware-Spezifikationen lesen?
A : Weil "es eine Kluft zwischen Kohlenstoff und Silizium gibt, die die Software nicht überbrücken kann" - Rahul Sonnad
Das oben Gesagte stellt jedoch kein Problem für Rechenalgorithmen ( Treibercode - Verarbeitung in der unteren Hälfte ) dar, da es auf einer Universal Turing-Maschine vollständig simuliert werden kann . Wenn das berechnete Ergebnis im mathematischen Bereich zutrifft , ist es sicher, dass es auch im physikalischen Bereich zutrifft .
Videovorträge zu Linux-Gerätetreibern (Lec. 17 & 18), Anatomie eines eingebetteten KMS-Treibers , Pin-Kontrolle und GPIO-Aktualisierung , gemeinsames Clock-Framework , Schreiben eines echten Linux-Treibers - Greg KH
static irqreturn_t phy_interrupt(int irq, void *phy_dat)
{
struct phy_device *phydev = phy_dat;
if (PHY_HALTED == phydev->state)
return IRQ_NONE; /* It can't be ours. */
/* The MDIO bus is not allowed to be written in interrupt
* context, so we need to disable the irq here. A work
* queue will write the PHY to disable and clear the
* interrupt, and then reenable the irq line.
*/
disable_irq_nosync(irq);
atomic_inc(&phydev->irq_disable);
queue_work(system_power_efficient_wq, &phydev->phy_queue);
return IRQ_HANDLED;
}
- Linux-Gerätetreiber - Jonathan Corbet, Alessandro Rubini und Greg Kroah-Hartman
- Wichtige Linux-Gerätetreiber - Sreekrishnan Venkateswaran
- Schreiben von Linux-Gerätetreibern - Jerry Cooperstein
- Programmierhandbuch für das Linux-Kernelmodul - Peter Jay Salzman, Michael Burian, Ori Pomerantz
- Linux PCMCIA Programmierhandbuch - David Hinds
- Linux SCSI Programmier Howto - Heiko Eibfeldt
- Handbuch zur seriellen Programmierung für POSIX-Betriebssysteme - Michael R. Sweet
- Linux-Grafiktreiber: eine Einführung - Stéphane Marchesin
- Programmieranleitung für Linux-USB-Gerätetreiber - Detlef Fliegl
- Das Linux- Kernelgerätemodell - Patrick Mochel
Kernel-Netzwerk (1 -> 2 -> 3 -> ...)
"Nennen Sie es einen Clan, nennen Sie es ein Netzwerk, nennen Sie es einen Stamm, nennen Sie es eine Familie: Was auch immer Sie es nennen, wer auch immer Sie sind, Sie brauchen eines." - Jane Howard
Das Verständnis eines Packet Walk-Through im Kernel ist ein Schlüssel zum Verständnis der Kernel-Vernetzung. Es ist ein Muss, wenn wir Netfilter- oder IPSec-Interna und mehr verstehen wollen. Die zwei wichtigsten Strukturen der Netzwerkschicht des Linux-Kernels sind: struct sk_buff
undstruct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
- Grundlegendes zu Linux-Netzwerk-Interna - Christian Benvenuti
- Linux Kernel Networking: Implementierung und Theorie - Rami Rosen
- UNIX-Netzwerkprogrammierung - W. Richard Stevens
- Der definitive Leitfaden zur Linux-Netzwerkprogrammierung - Keir Davis, John W. Turner, Nathan Yocom
- Der Linux TCP / IP Stack: Vernetzung für eingebettete Systeme - Thomas F. Herbert
- Linux Socket - Programmierung von Beispiel - Warren W. Homosexuell
- Linux Advanced Routing & Verkehrskontrolle HOWTO - Bert Hubert
Kernel-Debugging (1 -> 4 -> 9 -> ...)
Wenn man bei der Kommunikation nicht genau sagt, was man meint, wird es zwangsläufig Ärger geben. ~ Alan Turing über Computer
Brian W. Kernighan sagte in der Zeitung Unix for Beginners (1979): "Das effektivste Debugging-Tool ist immer noch sorgfältiges Überlegen, gepaart mit vernünftig platzierten Print-Anweisungen." Wenn Sie wissen, was zu sammeln ist, erhalten Sie schnell die richtigen Daten für eine schnelle Diagnose. Der große Informatiker Edsger Dijkstra sagte einmal, dass Tests das Vorhandensein von Fehlern, nicht aber deren Abwesenheit nachweisen können. Gute Ermittlungspraktiken sollten die Notwendigkeit einer raschen Lösung von Problemen, die Notwendigkeit, Ihre Fähigkeiten auszubauen, und den effektiven Einsatz von Sachverständigen in Einklang bringen.
Es gibt Zeiten, in denen Sie den Tiefpunkt erreichen, nichts zu funktionieren scheint und Ihnen alle Optionen ausgehen. Dann beginnt das eigentliche Debuggen. Ein Fehler kann die Pause bieten, die Sie benötigen, um sich von einer Fixierung auf die unwirksame Lösung zu lösen.
Videovorträge zu Kernel- Debugging und -Profiling , Core-Dump-Analyse , Multicore-Debugging mit GDB , Steuerung von Multi-Core-Race-Bedingungen , Debugging von Elektronik
/* Buggy Code -- Stack frame problem
* If you require information, do not free memory containing the information
*/
char *initialize() {
char string[80];
char* ptr = string;
return ptr;
}
int main() {
char *myval = initialize();
do_something_with(myval);
}
/* “When debugging, novices insert corrective code; experts remove defective code.”
* – Richard Pattis
#if DEBUG
printk("The above can be considered as Development and Review in Industrial Practises");
#endif
*/
- Linux Debugging und Performance Tuning - Steve Best
- Debugging-Techniken für Linux-Anwendungen - Aurelian Melinte
- Debugging mit GDB: Der GNU Source-Level-Debugger - Roland H. Pesch
- Debugging von Embedded Linux - Christopher Hallinan
- Die Kunst des Debuggens mit GDB, DDD und Eclipse - Norman S. Matloff
- Warum Programme scheitern: Eine Anleitung zum systematischen Debuggen - Andreas Zeller
- Software-Exorzismus: Ein Handbuch zum Debuggen und Optimieren von Legacy-Code - Bill Blunden
- Debugging: Auffinden schwer zu lösender Software- und Hardwareprobleme - David J. Agans
- Debuggen durch Denken: Ein multidisziplinärer Ansatz - Robert Charles Metzger
- Finden Sie den Bug: Ein Buch mit falschen Programmen - Adam Barr
Dateisysteme (1 -> 2 -> 6 -> ...)
"Ich wollte virtuellen Speicher haben, zumindest weil er mit Dateisystemen gekoppelt ist." - Ken Thompson
Auf einem UNIX-System ist alles eine Datei. Wenn etwas keine Datei ist, ist es ein Prozess, mit Ausnahme von Named Pipes und Sockets. In einem Dateisystem wird eine Datei durch inode
eine Art Seriennummer dargestellt, die Informationen zu den tatsächlichen Daten enthält, aus denen die Datei besteht. Das virtuelle Linux-Dateisystem VFS
speichert Informationen aus jedem Dateisystem im Speicher, während es bereitgestellt und verwendet wird. Es muss sehr sorgfältig vorgegangen werden, um das Dateisystem korrekt zu aktualisieren, da die Daten in diesen Caches geändert werden, wenn Dateien und Verzeichnisse erstellt, geschrieben und gelöscht werden. Der wichtigste dieser Caches ist der Puffercache, der in die Art und Weise integriert ist, in der die einzelnen Dateisysteme auf ihre zugrunde liegenden Blockspeichergeräte zugreifen.
Videovorträge zu Speichersystemen , Flash Friendly File System
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;
int fd = build_open_flags(flags, mode, &op);
struct filename *tmp;
if (fd)
return fd;
tmp = getname(filename);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
fd = get_unused_fd_flags(flags);
if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp, &op);
if (IS_ERR(f)) {
put_unused_fd(fd);
fd = PTR_ERR(f);
} else {
fsnotify_open(f);
fd_install(fd, f);
}
}
putname(tmp);
return fd;
}
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
- Linux-Dateisysteme - Moshe Bar
- Linux-Dateisysteme - William Von Hagen
- UNIX-Dateisysteme: Evolution, Design und Implementierung - Steve D. Pate
- Praktisches Dateisystemdesign - Dominic Giampaolo
- Dateisystemforensische Analyse - Brian Carrier
- Hierarchie des Linux-Dateisystems - Binh Nguyen
- BTRFS: Das Linux-B-Tree-Dateisystem - Ohad Rodeh
- StegFS: Ein steganographisches Dateisystem für Linux - Andrew D. McDonald, Markus G. Kuhn
Sicherheit (1 -> 2 -> 8 -> 4 -> 3 -> ...)
"UNIX sollte seine Benutzer nicht davon abhalten, dumme Dinge zu tun, da dies sie auch davon abhalten würde, kluge Dinge zu tun". - Doug Gwyn
Keine Technik funktioniert, wenn sie nicht verwendet wird. Ethik ändert sich mit der Technologie.
" F × S = k " ist das Produkt von Freiheit und Sicherheit eine Konstante. - Nivens Gesetze
Kryptographie bildet die Basis des Online-Vertrauens. Beim Hacking werden Sicherheitskontrollen entweder in technischer, physischer oder menschlicher Hinsicht ausgenutzt. Das Schützen des Kernels vor anderen laufenden Programmen ist ein erster Schritt auf dem Weg zu einem sicheren und stabilen System, aber dies reicht offensichtlich nicht aus: Es muss auch ein gewisses Maß an Schutz zwischen verschiedenen User-Land-Anwendungen bestehen. Exploits können auf lokale oder Remote-Dienste abzielen.
"Du kannst dein Schicksal nicht hacken, brutale Gewalt ... du brauchst eine Hintertür, einen Seitenkanal ins Leben."
- Clyde Dsouza
Computer lösen keine Probleme, sie führen Lösungen aus. Hinter jedem nicht deterministischen algorithmischen Code steckt ein entschlossener Verstand.
- / var / log / dmesg
Videovorträge zu Kryptografie und Netzwerksicherheit , Namespaces für Sicherheit , Schutz vor Remoteangriffen , Secure Embedded Linux
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
- Hacking: Die Kunst der Ausbeutung - Jon Erickson
- Das Rootkit-Arsenal: Flucht und Ausweichen in den dunklen Ecken des Systems - Bill Blunden
- Offengelegtes Hacking: Geheimnisse der Netzwerksicherheit - Stuart McClure, Joel Scambray, George Kurtz
- Ein Leitfaden zur Kernausbeutung: Angriff auf den Kern - Enrico Perla, Massimiliano Oldani
- Die Kunst der Erinnerungsforensik - Michael Hale Ligh, Andrew Case, Jamie Levy, AAron Walters
- Praktisches Reverse Engineering - Bruce Dang, Alexandre Gazet, Elias Bachaalany
- Praktische Malware-Analyse - Michael Sikorski, Andrew Honig
- Maximale Linux-Sicherheit: Ein Hacker-Handbuch zum Schutz Ihres Linux-Servers - anonym
- Linux-Sicherheit - Craig Hunt
- Reale Linux-Sicherheit - Bob Toxen
Kernelquelle (0,11 -> 2,4 -> 2,6 -> 3,18)
"Wie Wein reift die Beherrschung der Kernel-Programmierung mit der Zeit. Im Gegensatz zu Wein wird sie dabei jedoch süßer." - Lawrence Mucheka
Sie denken vielleicht nicht, dass Programmierer Künstler sind, aber das Programmieren ist ein äußerst kreativer Beruf. Es ist logische Kreativität. Die Informatikausbildung kann niemanden zu einem erfahrenen Programmierer machen, ebenso wenig wie das Studium von Pinseln und Pigmenten jemanden zu einem erfahrenen Maler machen kann. Wie Sie bereits wissen, gibt es einen Unterschied zwischen dem Kennen des Pfades und dem Gehen des Pfades. Es ist äußerst wichtig, die Ärmel hochzukrempeln und sich die Hände mit dem Kernel-Quellcode schmutzig zu machen. Schließlich werden Sie mit Ihrem so gewonnenen Kernel- Wissen überall glänzen .
Unreife Codierer imitieren; reife Programmierer stehlen; Schlechte Codierer entstellen, was sie nehmen, und gute Codierer machen es zu etwas Besserem oder zumindest etwas Anderem. Der gute Kodierer schweißt seinen Diebstahl zu einem ganz anderen Gefühl zusammen, als das, von dem er gerissen wurde.
Videovorträge zu Kernel-Rezepten
linux-0.11
├── boot
│ ├── bootsect.s head.s setup.s
├── fs
│ ├── bitmap.c block_dev.c buffer.c char_dev.c exec.c
│ ├── fcntl.c file_dev.c file_table.c inode.c ioctl.c
│ ├── namei.c open.c pipe.c read_write.c
│ ├── stat.c super.c truncate.c
├── include
│ ├── a.out.h const.h ctype.h errno.h fcntl.h
│ ├── signal.h stdarg.h stddef.h string.h termios.h
│ ├── time.h unistd.h utime.h
│ ├── asm
│ │ ├── io.h memory.h segment.h system.h
│ ├── linux
│ │ ├── config.h fdreg.h fs.h hdreg.h head.h
│ │ ├── kernel.h mm.h sched.h sys.h tty.h
│ ├── sys
│ │ ├── stat.h times.h types.h utsname.h wait.h
├── init
│ └── main.c
├── kernel
│ ├── asm.s exit.c fork.c mktime.c panic.c
│ ├── printk.c sched.c signal.c sys.c system_calls.s
│ ├── traps.c vsprintf.c
│ ├── blk_drv
│ │ ├── blk.h floppy.c hd.c ll_rw_blk.c ramdisk.c
│ ├── chr_drv
│ │ ├── console.c keyboard.S rs_io.s
│ │ ├── serial.c tty_io.c tty_ioctl.c
│ ├── math
│ │ ├── math_emulate.c
├── lib
│ ├── close.c ctype.c dup.c errno.c execve.c _exit.c
│ ├── malloc.c open.c setsid.c string.c wait.c write.c
├── Makefile
├── mm
│ ├── memory.c page.s
└── tools
└── build.c
- Anfänger beginnen mit Linux 0.11 (weniger als 20.000 Zeilen Quellcode). Nach 20 Jahren Entwicklung ist Linux im Vergleich zu Linux 0.11 sehr umfangreich, komplex und schwer zu erlernen. Das Designkonzept und die Hauptstruktur haben jedoch keine grundlegenden Änderungen. Das Erlernen von Linux 0.11 hat nach wie vor eine wichtige praktische Bedeutung.
- Pflichtlektüre für Kernel-Hacker =>
Linux_source_dir/Documentation/*
- Sie sollten in mindestens einer Kernel-Mailingliste angemeldet und aktiv sein. Beginnen Sie mit Kernel-Neulingen .
- Sie müssen nicht den vollständigen Quellcode lesen. Sobald Sie mit den Kernel-APIs und ihrer Verwendung vertraut sind, beginnen Sie direkt mit dem Quellcode des Subsystems, an dem Sie interessiert sind. Sie können auch eigene Plug-n-Play-Module schreiben, um mit dem Kernel zu experimentieren.
- Gerätetreiberautoren würden von einer eigenen dedizierten Hardware profitieren. Beginnen Sie mit Raspberry Pi .