**TODO** +editPic: Linux Kernel Developer -> (Ring Layer 0)
+addSection: Kernel Virtualization Engine
KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.
Рекомендуемые книги для неинициализированныхvoid *i
«Люди не понимают книг до тех пор, пока у них не будет определенного количества жизни, или, во всяком случае, ни один человек не поймет глубокой книги, пока не увидит и не прожит хотя бы часть ее содержания». –Эзра Паунд
Путешествие в тысячу кодовых миль должно начинаться с одного шага. Если вы не уверены, с какой из следующих книг начать, не волнуйтесь, выберите любую из ваших книг. Не все те, кто бродят теряются. Поскольку все дороги в конечном итоге соединяются с шоссе , вы будете исследовать новые вещи в своем путешествии по ядру, поскольку страницы развиваются без каких-либо тупиков и, в конечном счете, подключаются к code-set
. Читайте с умом и помните: код не литература .
То, что осталось, - это не вещь, не эмоция, не изображение, не ментальная картина, не память и даже не идея. Это функция. Процесс какой-то. Аспект Жизни, который можно описать как функцию чего-то «большего». И, следовательно, кажется, что это на самом деле не «отделено» от этого чего-то еще. Подобно функции ножа - резать что-то - на самом деле не отдельно от самого ножа. Эта функция может использоваться или не использоваться в данный момент, но потенциально НИКОГДА не является отдельной.
Соломай Штрассен дерандомизированный алгоритм для теста простоты :
Читайте, чтобы не противоречить и не путать; ни верить, ни принимать как должное; ни найти разговоров и бесед; но взвесить и рассмотреть. Некоторые книги нужно попробовать, другие проглотить, а некоторые - разжевать и переварить: то есть некоторые книги следует читать только по частям, другие читать, но не с любопытством, а некоторые - полностью. и с усердием и вниманием.
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)
«Природа не имеет ни ядра, ни оболочки; она - все одновременно »- Иоганн Вольфганг фон Гете
Читатель должен хорошо разбираться в понятиях операционной системы ; правильное понимание длительных процессов и их различий с процессами с короткими очередями исполнения; отказоустойчивость при выполнении мягких и жестких ограничений в реальном времени. Во время чтения важно понимать и n/ack
выбор дизайна, сделанный исходным кодом ядра Linux в основных подсистемах.
Потоки [и] сигналы [являются] зависимым от платформы следом страдания, отчаяния, ужаса и безумия (~ Энтони Баксте). При этом вы должны быть самооценочным экспертом C, прежде чем углубляться в ядро. Вы также должны иметь хороший опыт работы со связанными списками, стеками, очередями, деревьями красных черных, хэш-функциями и др.
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;
}
Красота и искусство исходного кода ядра Linux заключается в преднамеренном запутывании кода, которое используется вместе. Это часто необходимо, чтобы передать вычислительное значение, включающее две или более операций, чистым и элегантным способом. Это особенно верно при написании кода для многоядерной архитектуры.
Видео Лекция по системам реального времени , задачи календарного планирования , Memory Compression , барьеры памяти , SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
- Разработка ядра Linux - Роберт Лав
- Понимание ядра Linux - Даниэль П. Бове, Марко Чезати
- Искусство Linux KerneL Design - Ян Лисян
- Профессиональная архитектура ядра Linux - Вольфганг Маурер
- Проект операционной системы UNIX - Морис Дж. Бах
- Понимание менеджера виртуальной памяти Linux - Мел Горман
- Внутреннее ядро Linux - Тигран Айвазян
- Учебник по встроенному Linux - Кристофер Халлинан
Драйверы устройств Linux (1 -> 2 -> 4 -> 3 -> 8 -> ...)
«Музыка вас не увлекает. Вы должны нести ее строго своей способностью действительно сосредоточиться на этом маленьком маленьком ядре эмоций или истории». - Дебби Гарри
Ваша задача - установить высокоскоростной интерфейс связи между аппаратным устройством и программным ядром. Вам следует прочитать справочную таблицу / руководство по аппаратному обеспечению, чтобы понять поведение устройства, его состояния управления и данных, а также предоставляемые физические каналы. Знание ассемблера для вашей конкретной архитектуры и хорошее знание описания оборудования VLSI. Такие языки, как VHDL или Verilog, помогут вам в долгосрочной перспективе.
В : Но почему я должен читать спецификации оборудования?
A : Потому что «существует пропасть из углерода и кремния, которую программное обеспечение не может преодолеть» - Рахул Соннад
Тем не менее, вышеизложенное не представляет проблемы для вычислительных алгоритмов ( код драйвера - обработка нижней половины ), поскольку его можно полностью смоделировать на универсальной машине Тьюринга . Если вычисленный результат верен в математической области , то несомненно, что он верен и в физической области .
Видеолекции по драйверам устройств Linux (Лек. 17 и 18), Анатомия встроенного драйвера KMS , Pin Control и обновление GPIO , Common Clock Framework , Написать настоящий драйвер Linux - Грег КХ
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 - Джонатан Корбет, Алессандро Рубини и Грег Кроа-Хартман
- Основные драйверы устройств Linux - Sreekrishnan Venkateswaran
- Написание драйверов устройств для Linux - Джерри Куперстейн
- Руководство по программированию модуля ядра Linux - Питер Джей Зальцман, Майкл Бурьян, Ори Померанц
- Руководство программиста Linux PCMCIA - Дэвид Хиндс
- Linux SCSI Programming Howto - Хейко Айбфельдт
- Руководство по последовательному программированию для операционных систем POSIX - Майкл Р. Свит
- Драйверы графики Linux: введение - Стефан Марчесин
- Руководство по программированию для Linux USB драйверов устройств - Detlef Fliegl
- Модель устройства ядра Linux - Патрик Мохель
Сеть ядра (1 -> 2 -> 3 -> ...)
«Назовите это кланом, назовите это сетью, назовите это племенем, назовите это семьей: как бы вы это ни называли, кем бы вы ни были, вам нужен один» - Джейн Ховард
Понимание прохождения пакетов в ядре является ключом к пониманию работы ядра в сети. Понимание этого является обязательным, если мы хотим понять внутренности Netfilter или IPSec и многое другое. Два наиболее важных структур сети Linux ядра слоя: struct sk_buff
иstruct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
- Понимание внутренних сетей Linux - Кристиан Бенвенути
- Сеть ядра Linux: реализация и теория - Рами Розен
- Сетевое программирование в UNIX - У. Ричард Стивенс
- Полное руководство по сетевому программированию в Linux - Кейр Дэвис, Джон У. Тернер, Натан Йоком
- Стек TCP / IP в Linux: сеть для встроенных систем - Томас Ф. Герберт
- Программирование сокетов Linux на примере - Уоррен В. Гей
- Linux Advanced Routing & Traffic Control HOWTO - Берт Хьюберт
Отладка ядра (1 -> 4 -> 9 -> ...)
Если вы не общаетесь с ним, то точно говорите, что он имеет в виду, проблема неизбежна. ~ Алан Тьюринг, о компьютерах
Брайан В. Керниган, в статье «Unix для начинающих» (1979), сказал: «Самый эффективный инструмент отладки - это все еще тщательно продуманный в сочетании с разумно размещенными печатными заявлениями». Знание того, что собирать, поможет вам быстро получить правильные данные для быстрой диагностики. Великий компьютерщик Эдсгер Дейкстра однажды сказал, что тестирование может продемонстрировать наличие ошибок, но не их отсутствие. Надлежащая практика проведения расследований должна сочетать необходимость быстрого решения проблем, необходимость развития навыков и эффективного использования экспертов в данной области.
Есть моменты, когда вы достигаете предела, кажется, что ничего не работает, и у вас заканчиваются все ваши варианты. Затем начинается настоящая отладка. Ошибка может обеспечить перерыв, который вам нужен, чтобы освободиться от зацикливания на неэффективном решении.
Видео Лекция по Kernel Debug и профилирование , дампы памяти , анализ , многожильная Отладка с помощью GDB , контроллинг Многоядерного Race Условие , отладка электроника
/* 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 и настройка производительности - Стив Бест
- Методы отладки приложений Linux - Aurelian Melinte
- Отладка с помощью GDB: отладчик уровня исходного кода GNU - Роланд Х. Пеш
- Отладка встроенного Linux - Кристофер Халлинан
- Искусство отладки с помощью GDB, DDD и Eclipse - Норман С. Матлофф
- Почему программы терпят неудачу: руководство по систематической отладке - Андреас Зеллер
- Программный экзорцизм: руководство по отладке и оптимизации устаревшего кода - Билл Блунден
- Отладка: поиск наиболее неуловимых проблем с программным и аппаратным обеспечением - Дэвид Дж. Аганс
- Отладка мышлением: междисциплинарный подход - Роберт Чарльз Метцгер
- Найдите ошибку: Книга неправильных программ - Адам Барр
Файловые системы (1 -> 2 -> 6 -> ...)
«Я хотел иметь виртуальную память, по крайней мере, так как она связана с файловыми системами». - Кен Томпсон
В системе UNIX все является файлом; если что-то не является файлом, это процесс, за исключением именованных каналов и сокетов. В файловой системе файл представлен inode
своего рода серийным номером, содержащим информацию о фактических данных, составляющих файл. Виртуальная файловая система Linux VFS
кэширует информацию в памяти из каждой файловой системы, когда она монтируется и используется. Необходимо тщательно позаботиться о корректном обновлении файловой системы, поскольку данные в этих кэшах изменяются по мере того, как файлы и каталоги создаются, записываются и удаляются. Наиболее важным из этих кэшей является буферный кэш, который интегрирован в способ доступа отдельных файловых систем к своим базовым блочным устройствам хранения.
Видеолекции по системам хранения , 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 - Моше Бар
- Файловые системы Linux - Уильям фон Хаген
- Файловые системы UNIX: эволюция, проектирование и реализация - Стив Д. Пэйт
- Практический дизайн файловой системы - Доминик Джампаоло
- Криминалистический анализ файловой системы - Brian Carrier
- Иерархия файловой системы Linux - Бин Нгуен
- BTRFS: Файловая система Linux B-tree - Охад Родех
- StegFS: стеганографическая файловая система для Linux - Эндрю Д. Макдональд, Маркус Г. Кун
Безопасность (1 -> 2 -> 8 -> 4 -> 3 -> ...)
«UNIX не был разработан, чтобы мешать своим пользователям делать глупости, поскольку это также мешало бы им делать умные вещи». - Дуг Гвин
Никакая техника не работает, если она не используется. Этика меняется с технологией.
« F × S = k » произведение свободы и безопасности является константой. - Законы Нивена
Криптография формирует основу доверия в Интернете. Хакерство - это использование средств контроля безопасности в техническом, физическом или человеческом элементах. Защита ядра от других работающих программ - это первый шаг к безопасной и стабильной системе, но этого явно недостаточно: должна также существовать некоторая степень защиты между различными пользовательскими приложениями. Эксплойты могут быть нацелены на локальные или удаленные сервисы.
«Вы не можете взломать свою судьбу, грубую силу ... вам нужна задняя дверь, боковой канал в Жизнь»
- Клайд Дсоуза
Компьютеры не решают проблемы, они выполняют решения. За каждым недетерминированным алгоритмическим кодом стоит определенный ум.
- / var / log / dmesg
Видеолекции по криптографии и сетевой безопасности , пространствам имен для безопасности , защите от удаленных атак , защищенному встраиваемому Linux
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
- Взлом: Искусство Эксплуатации - Джон Эриксон
- Арсенал руткитов: побег и уклонение в темных углах системы - Билл Блунден
- Раскрытие взлома: секреты сетевой безопасности - Стюарт МакКлюр, Джоэл Скамбрей, Джордж Курц
- Руководство по эксплуатации ядра: атака на ядро - Энрико Перла, Массимилиано Олдани
- Криминалистическое искусство памяти - Майкл Хейл Лайт, Эндрю Кейс, Джейми Леви, Аарон Уолтерс
- Практический реверс-инжиниринг - Брюс Данг, Александр Газет, Элиас Бачаланы
- Практический анализ вредоносных программ - Майкл Сикорский, Эндрю Хониг
- Максимальная безопасность Linux: руководство хакера по защите вашего сервера Linux - анонимно
- Безопасность Linux - Крейг Хант
- Реальная безопасность Linux - Боб Токсен
Источник ядра (0.11 -> 2.4 -> 2.6 -> 3.18)
«Как и Wine, мастерство программирования ядра со временем созревает. Но, в отличие от Wine, оно становится слаще в процессе». - Лавренс Мучека
Вы можете не думать, что программисты - художники, но программирование - чрезвычайно творческая профессия. Это основанное на логике творчество. Образование в области компьютерных наук не может сделать кого-либо опытным программистом, так же как изучение кистей и пигмента не может сделать кого-то опытным художником. Как вы уже знаете, есть разница между знанием пути и ходьбой пути; крайне важно закатать рукава и запачкать руки исходным кодом ядра. Наконец, благодаря полученным таким образом знаниям ядра , куда бы вы ни пошли, вы будете сиять .
Незрелые кодеры имитируют; зрелые кодеры воруют; плохие кодеры портят то, что они берут, а хорошие кодеры превращают это во что-то лучшее или, по крайней мере, во что-то другое. Хороший кодер впадает в кражу целое чувство, которое является уникальным, совершенно отличным от того, из которого оно было порвано.
Видео лекции по рецептам ядра
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 0.11 (менее 20000 строк исходного кода). После 20 лет разработки, по сравнению с Linux 0.11, Linux стал очень большим, сложным и трудным для изучения. Но концепция дизайна и основная структура не имеют принципиальных изменений. Изучение Linux 0.11 по-прежнему имеет важное практическое значение.
- Обязательное чтение для Kernel Hackers =>
Linux_source_dir/Documentation/*
- Вы должны быть подписаны и активны хотя бы в одном списке рассылки ядра. Начните с ядра новичков .
- Вам не нужно читать полный исходный код. Когда вы ознакомитесь с API-интерфейсами ядра и его использованием, начните непосредственно с исходного кода интересующей вас подсистемы. Вы также можете начать с написания собственных модулей plug-n-play для экспериментов с ядром.
- Авторы драйверов устройств выиграют, имея собственное выделенное оборудование. Начните с Raspberry Pi .