Interesuje mnie modyfikowanie wewnętrznych elementów jądra, stosowanie poprawek, obsługa sterowników urządzeń i modułów dla własnej osobistej zabawy.
Czy istnieje kompleksowe źródło hakowania jądra, przeznaczone dla doświadczonych programistów?
Interesuje mnie modyfikowanie wewnętrznych elementów jądra, stosowanie poprawek, obsługa sterowników urządzeń i modułów dla własnej osobistej zabawy.
Czy istnieje kompleksowe źródło hakowania jądra, przeznaczone dla doświadczonych programistów?
Odpowiedzi:
**TODO** +editPic: Linux Kernel Developer -> (Ring Layer 0)
+addSection: Kernel Virtualization Engine
KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.
Polecane książki dla niezainicjowanych
void *i
„Ludzie nie rozumieją książek, dopóki nie osiągną pewnej ilości życia, a przynajmniej nikt nie zrozumie głębokiej książki, dopóki nie zobaczy i nie przeżyje przynajmniej części jej zawartości”. –Ezra Funt
Podróż tysiąca mil kodowych musi rozpocząć się od jednego kroku. Jeśli masz wątpliwości co do której z poniższych książek na początek, nie martw się, wybierz dowolną z nich. Nie wszyscy którzy błądzą są zagubieni. Ponieważ wszystkie drogi ostatecznie łączą się z autostradami , podczas podróży po jądrze będziesz odkrywać nowe rzeczy, gdy strony będą się rozwijać, nie spotykając żadnych ślepych zaułków, i ostatecznie połączą się z siecią code-set
. Czytaj uważnie i pamiętaj: Kod to nie literatura .
To, co zostało, nie jest rzeczą ani emocją, ani obrazem, ani obrazem mentalnym, ani wspomnieniem, ani nawet pomysłem. To jest funkcja. Jakiś proces. Aspekt życia, który można opisać jako funkcję czegoś „większego”. I dlatego wydaje się, że tak naprawdę nie jest „oddzielone” od tego czegoś innego. Podobnie jak funkcja noża - przecinanie czegoś - w rzeczywistości nie jest oddzielona od samego noża. Funkcja może być lub może nie być w tej chwili używana, ale potencjalnie NIGDY nie jest osobna.
Algorytm derandomizowany Solovaya Strassena dla testu pierwotności :
Czytaj, aby nie zaprzeczać i nie spierać się; ani nie wierzyć i brać za pewnik; ani nie znaleźć mowy ani dyskursu; ale ważyć i rozważać. Niektóre książki mają być degustowane, inne połykane, a niektóre do żucia i trawienia: to znaczy, niektóre książki należy czytać tylko w częściach, inne do przeczytania, ale nie ciekawie, a niektóre do przeczytania w całości oraz z należytą starannością i uwagą.
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();
}
}
Core Linux (5 -> 1 -> 3 -> 2 -> 7 -> 4 -> 6)
„Natura nie ma ani jądra, ani skorupy; jest wszystkim naraz ”- Johann Wolfgang von Goethe
Czytelnik powinien dobrze znać koncepcje systemu operacyjnego ; rzetelne zrozumienie długotrwałych procesów i ich różnic z procesami o krótkich seriach wykonania; odporność na uszkodzenia przy jednoczesnym spełnieniu miękkich i twardych ograniczeń w czasie rzeczywistym. Podczas czytania ważne jest zrozumienie i n/ack
wyborów projektowych dokonanych przez źródło jądra Linux w podstawowych podsystemach.
Wątki [i] sygnały [są] zależną od platformy ścieżką nędzy, rozpaczy, horroru i szaleństwa (~ Anthony Baxte). Biorąc to pod uwagę, powinieneś być samoocennym ekspertem C, zanim zanurzysz się w jądrze. Powinieneś również mieć dobre doświadczenie z połączonymi listami, stosami, kolejkami, drzewami Czerwonej Czarnej, funkcjami skrótu i innymi.
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;
}
Piękno i sztuka źródła jądra Linuksa polegają na celowym zaciemnianiu kodu stosowanym razem. Jest to często konieczne, aby przekazać znaczenie obliczeniowe obejmujące dwie lub więcej operacji w czysty i elegancki sposób. Jest to szczególnie prawdziwe podczas pisania kodu dla architektury wielordzeniowej.
Wykłady wideo na temat Real-Time Systems , Planowanie zadań , kompresja pamięci , bariera pamięci , SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
Sterowniki urządzeń Linux (1 -> 2 -> 4 -> 3 -> 8 -> ...)
„Muzyka niesie Cię ze sobą. Musisz nosić ją ze sobą tylko dzięki swojej zdolności do skupienia się na tym małym jądrze emocji lub historii”. - Debbie Harry
Twoim zadaniem jest w zasadzie ustanowienie szybkiego interfejsu komunikacyjnego między urządzeniem sprzętowym a jądrem oprogramowania. Należy zapoznać się z arkuszem danych / instrukcją obsługi sprzętu, aby zrozumieć zachowanie urządzenia i jego kontroli oraz stanów danych i udostępnionych kanałów fizycznych. Znajomość asemblera dla konkretnej architektury i rzetelna znajomość opisu sprzętu VLSI Języki takie jak VHDL lub Verilog pomogą Ci na dłuższą metę.
P : Ale dlaczego muszę czytać specyfikacje sprzętu?
Odp . : Ponieważ „istnieje przepaść węgla i krzemu, których oprogramowanie nie może łączyć” - Rahul Sonnad
Powyższe nie stanowi jednak problemu dla algorytmów obliczeniowych ( kod sterownika - przetwarzanie w dolnej połowie ), ponieważ można je w pełni symulować na uniwersalnej maszynie Turinga . Jeśli obliczony wynik jest prawdziwy w dziedzinie matematycznej , jest pewne, że jest on również prawdziwy w dziedzinie fizycznej .
Wykłady wideo na temat sterowników urządzeń dla systemu Linux (Wy 17 i 18), Anatomia wbudowanego sterownika KMS , Kontrola pinów i Aktualizacja GPIO , Common Clock Framework , Napisz prawdziwy sterownik dla systemu Linux - 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;
}
Sieć jądra (1 -> 2 -> 3 -> ...)
„Nazwij to klanem, nazwij to siecią, nazwij to plemieniem, nazwij to rodziną: cokolwiek nazwiesz, kimkolwiek jesteś, potrzebujesz go.” - Jane Howard
Zrozumienie przejścia pakietów w jądrze jest kluczem do zrozumienia sieci jądra. Zrozumienie tego jest koniecznością, jeśli chcemy zrozumieć wewnętrzne funkcje Netfilter lub IPSec i więcej. Dwie najważniejsze struktury warstwy sieci jądra Linuksa to: struct sk_buff
istruct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
Debugowanie jądra (1 -> 4 -> 9 -> ...)
O ile w komunikowaniu się z nim nie powie się dokładnie, co to znaczy, kłopoty na pewno przyniosą skutek. ~ Alan Turing, o komputerach
Brian W. Kernighan w artykule Unix for Beginners (1979) powiedział: „Najskuteczniejszym narzędziem do debugowania jest staranne przemyślenie w połączeniu z rozsądnie umieszczonymi instrukcjami drukowania”. Wiedza o tym, co należy zebrać, pomoże ci szybko uzyskać odpowiednie dane do szybkiej diagnozy. Wielki informatyk Edsger Dijkstra powiedział kiedyś, że testy mogą wykazać obecność błędów, ale nie ich brak. Dobre praktyki dochodzeniowe powinny równoważyć potrzebę szybkiego rozwiązywania problemów, potrzebę rozwijania umiejętności oraz efektywne wykorzystanie ekspertów w danej dziedzinie.
Są chwile, kiedy osiągasz dno, wydaje się, że nic nie działa i brakuje Ci wszystkich opcji. Wtedy zaczyna się prawdziwe debugowanie. Błąd może zapewnić przerwę potrzebną do oderwania się od fiksacji na nieskutecznym rozwiązaniu.
Wykłady wideo na temat debugowania i profilowania jądra , analizy zrzutu rdzenia , debugowania wielordzeniowego z GDB , kontrolowania warunków wyścigu wielordzeniowego , debugowania elektroniki
/* 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
*/
Systemy plików (1 -> 2 -> 6 -> ...)
„Chciałem mieć pamięć wirtualną, przynajmniej w połączeniu z systemami plików”. - Ken Thompson
W systemie UNIX wszystko jest plikiem; jeśli coś nie jest plikiem, jest to proces, z wyjątkiem nazwanych potoków i gniazd. W systemie plików plik jest reprezentowany przez inode
rodzaj numeru seryjnego zawierającego informacje o rzeczywistych danych, z których składa się plik. Wirtualny system plików Linux VFS
buforuje informacje w pamięci z każdego systemu plików, gdy jest on montowany i używany. Należy dołożyć starań, aby poprawnie zaktualizować system plików, ponieważ dane w tych pamięciach podręcznych są modyfikowane podczas tworzenia, zapisywania i usuwania plików i katalogów. Najważniejszym z tych buforów jest bufor buforów, zintegrowany ze sposobem, w jaki poszczególne systemy plików uzyskują dostęp do swoich podstawowych blokowych urządzeń magazynujących.
Wykłady wideo na temat systemów pamięci masowej , systemu plików Flash
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);
}
Bezpieczeństwo (1 -> 2 -> 8 -> 4 -> 3 -> ...)
„UNIX nie został zaprojektowany, aby powstrzymać użytkowników przed robieniem głupich rzeczy, ponieważ powstrzymałoby ich to także od robienia mądrych rzeczy”. - Doug Gwyn
Żadna technika nie działa, jeśli nie jest używana. Etyka zmienia się wraz z technologią.
„ F × S = k ” iloczyn wolności i bezpieczeństwa jest stały. - Prawa Niven
Kryptografia stanowi podstawę zaufania online. Hakowanie wykorzystuje mechanizmy kontroli bezpieczeństwa w elementach technicznych, fizycznych lub ludzkich. Ochrona jądra przed innymi uruchomionymi programami jest pierwszym krokiem w kierunku bezpiecznego i stabilnego systemu, ale oczywiście to nie wystarczy: musi istnieć pewien stopień ochrony między różnymi aplikacjami użytkowników. Exploity mogą atakować lokalne lub zdalne usługi.
„Nie możesz zhakować swojego przeznaczenia, brutalna siła ... potrzebujesz tylnych drzwi, bocznego kanału do życia.” - Clyde Dsouza
Komputery nie rozwiązują problemów, wykonują rozwiązania. Za każdym niedeterministycznym kodem algorytmicznym kryje się zdecydowany umysł. - / var / log / dmesg
Wykłady wideo na temat kryptografii i bezpieczeństwa sieci , przestrzeni nazw dla bezpieczeństwa , ochrony przed atakami zdalnymi , Secure Embedded Linux
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
Źródło jądra (0,11 -> 2,4 -> 2,6 -> 3,18)
„Podobnie jak wino, opanowanie programowania jądra dojrzewa z czasem. Ale w przeciwieństwie do wina staje się słodsze”. - Lawrence Mucheka
Możesz nie myśleć, że programiści to artyści, ale programowanie to niezwykle kreatywny zawód. To kreatywność oparta na logice. Edukacja informatyczna nie może uczynić nikogo ekspertem programistycznym bardziej niż studiowanie pędzli, a pigment może uczynić kogoś ekspertem malarzem. Jak już wiesz, istnieje różnica między poznaniem ścieżki a przejściem nią; niezwykle ważne jest zakasanie rękawów i zabrudzenie rąk kodem źródłowym jądra. Wreszcie, dzięki tak zdobytej wiedzy na temat jądra , gdziekolwiek się wybierzesz, zabłyśniesz .
Niedojrzali koderzy naśladują; dojrzałe kodery kradną; złe kodery niszczą to, co biorą, a dobrzy koderzy robią z tego coś lepszego, a przynajmniej innego. Dobry programista zgrzewa swoją kradzież w całość, która jest wyjątkowa, zupełnie inna niż ta, w której została rozdarta.
Wykłady wideo na temat przepisów dotyczących jądra
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
Linux_source_dir/Documentation/*
Linux Kernel Newbies to świetny zasób.
Proponuję przeczytać „ Jądro Linux w pigułce ” Grega Kroah-Hartmana i „ Zrozumienie jądra Linux ” Roberta Love'a. Musi czytać :)
Linux Device Drivers to kolejny dobry zasób. To dałoby ci inny sposób na wejście w wewnętrzne funkcjonowanie. Ze wstępu:
Na pierwszy rzut oka jest to książka o pisaniu sterowników urządzeń dla systemu Linux. To oczywiście godny cel; przepływ nowych produktów sprzętowych prawdopodobnie nie zwolni w najbliższym czasie, a ktoś będzie musiał sprawić, by wszystkie te nowe gadżety działały w systemie Linux. Ale ta książka jest również o tym, jak działa jądro Linuksa i jak dostosować jego działanie do twoich potrzeb lub zainteresowań. Linux jest systemem otwartym; dzięki tej książce mamy nadzieję, że będzie ona bardziej otwarta i dostępna dla większej społeczności programistów.
Zobacz projekt dokumentacji systemu Linux . W szczególności „Przewodnik po module jądra Linux”.
Linux Kernel 2.4 Internals to kolejny zasób online do obejrzenia. Wygląda na to, że zajmuje dość przyziemne podejście, zaczynając od rozruchu. Oto spis treści:
Aby jeszcze bardziej urozmaicić, pojawiło się nowe wydanie trzeciej wersji Linux Kernel Development autorstwa Roberta Lovea, a Slashdot ma recenzję.
Zacznij od Linux Kernel Primer autorstwa Claudii Salzberg i in. Dobry na początek dla początkujących. Książka Roberta Love'a zdecydowanie nie jest książką, od której powinni zacząć początkujący. Ostatnia książka jest powyżej poziomu pośredniego.