Я хочу изучить Linux-программирование ядра.
Что послужило бы отправной точкой для этого? Каковы могут быть некоторые из более простых проблем?
заблаговременно
Я хочу изучить Linux-программирование ядра.
Что послужило бы отправной точкой для этого? Каковы могут быть некоторые из более простых проблем?
заблаговременно
Попытайтесь заполучить книгу Роберта Люка по программированию ядра Linux. Его очень кратким и легко следовать.
После этого или вместе с этим вы можете взглянуть на "Понимание ядра Linux". Но я бы не рекомендовал его на ранних этапах.
Кроме того, посмотрите руководство по программированию ядра Linux. Поскольку многое может быть изучено при программировании модулей ядра, это руководство поможет вам. И да, для получения большой информации, обратитесь к подкаталогу "документации" в архиве источников ядра.
**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
"Мужчины не понимают книги, пока не имеют определенного количества жизни, или, во всяком случае, никто не понимает глубокую книгу, пока не увидит и не проживет хотя бы часть своего содержания". -Ezra Pound
Путешествие в тысячу миль кода должно начинаться с одного шага. Если вы в замешательстве о том, из какой из следующих книг для начала, не волнуйтесь, выберите любой из ваших вариантов. Не все те, кто бродят теряются. Поскольку все дороги в конечном счете соединяются с шоссе, вы будете исследовать новые вещи в своем путешествии по ярусу, поскольку страницы будут работать без каких-либо тупиков и, в конечном счете, подключиться к code-set
. Прочитайте с предупреждением и помните: Код не Литература.
То, что осталось, - это не вещь или эмоция, изображение или ментальная картина, память или даже идея. Это функция. Процесс какой-то. Аспект Жизни, который можно описать как функцию чего-то "большего". И, следовательно, кажется, что это не совсем "отдельно" от чего-то остальное. Как и функция ножа - разрезание чего-то - на самом деле не раздельно от самого ножа. Функция может быть или не использоваться в настоящий момент, но он НИКОГДА не будет отделен.
Переносимый алгоритм Solova Strassen для теста на первичность:
Читайте, чтобы не противоречить и не допускать; ни верить, ни считать само собой разумеющимся; ни найти разговоры и речи; но взвешивать и учитывать. Некоторые книги нужно пробовать, другие усвоить, а некоторые из них нужно пережевывать и переваривать: то есть некоторые книги должны читаться только по частям, другие - для чтения, но не любопытно, а некоторые из них должны быть прочитаны полностью, и с усердием и вниманием.
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, прежде чем погрузиться в ядро. Вы также должны иметь хороший опыт работы с Linked Lists, Stacks, Queues, Red Blacks Trees, Hash Functions и др.
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 заключаются в преднамеренном обфускации кода. Это часто необходимо для того, чтобы передать вычислительный смысл, включающий две или более операции, чистым и элегантным способом. Это особенно актуально при написании кода для многоядерной архитектуры.
Лекции по видео в системах реального времени, Планирование заданий, Сжатие памяти, Барьеры памяти, SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
Драйверы устройств Linux (1 → 2 → 4 → 3 → 8 → ...)
"Музыка не несет вас. Вы должны нести ее строго по своей способности просто сосредоточиться на этом маленьком ядре эмоций или истории". - Дебби Гарри
Ваша задача в основном заключается в установлении высокоскоростного коммуникационного интерфейса между аппаратным устройством и программным ядром. Вы должны прочитать техническое описание аппаратного обеспечения/руководство, чтобы понять поведение устройства, а также управлять его состояниями и физическими каналами. Знание сборки для вашей конкретной архитектуры и хорошее знание языков описания оборудования VLSI, таких как VHDL или Verilog, поможет вам в конечном итоге.
Q: Но почему мне нужно читать спецификации оборудования?
A: Потому что "Есть пропасть углерода и кремния, программное обеспечение не может моститься" - Рахул Соннад
Однако вышеизложенное не представляет проблемы для вычислительных алгоритмов (Код драйвера - нижняя половина обработки), так как он может быть полностью смоделирован на универсальной машине Тьюринга . Если вычисленный результат выполняется в математическом домене, то он уверен, что он также верен в физическом домене .
Лекции по видео на драйверах устройств Linux (Lec. 17 и 18), Анатомия Драйвер встроенного KMS, Управление контактами и обновление GPIO, Общие рамки часов, Написать реальный драйвер 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;
}
Сеть ядра (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);
}
Отладка ядра (1 → 4 → 9 → ...)
Если в общении с ним не говорится точно, что означает, проблема неизбежно приведет к результату. ~ Алан Тьюринг, о компьютерах
Брайан У. Керниган в статье Unix for Beginners (1979) сказал: "Самый эффективный инструмент отладки все еще тщательно продуман, в сочетании с разумно размещенными заявлениями печати". Знание того, что собирать, поможет вам быстро получить нужные данные для быстрого диагноза. Великий ученый-компьютерщик Эдсгер Дейкстра однажды сказал, что тестирование может продемонстрировать наличие ошибок, но не их отсутствие. Хорошие методы расследования должны уравновешивать необходимость быстрого решения проблем, необходимость создания ваших навыков и эффективного использования экспертами по предмету.
Бывают случаи, когда вы ударяете рок-дно, ничего не работает, и у вас заканчиваются все ваши варианты. Это то, что начинается настоящая отладка. Ошибка может обеспечить перерыв, необходимый для освобождения от фиксации на неэффективном решении.
Лекции по видео по отладке и профилированию ядра, Анализ дампа ядра, Многопользовательская отладка с помощью GDB, Управление многоядерными условиями гонки, Отладка электроники
/* 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
*/
Файловые системы (1 → 2 → 6 → ...)
"Я хотел иметь виртуальную память, по крайней мере, в сочетании с файловыми системами". - Кен Томпсон
В системе UNIX все является файлом; если что-то не является файлом, это процесс, за исключением именованных каналов и сокетов. В файловой системе файл представлен inode
, своего рода серийный номер, содержащий информацию о фактических данных, составляющих файл. Виртуальная файловая система Linux VFS
кэширует информацию в памяти из каждой файловой системы по мере ее установки и использования. Необходимо много внимания, чтобы правильно обновлять файловую систему, поскольку данные в этих кэшах изменяются по мере создания файлов и каталогов, их записи и удаления. Самым важным из этих кэшей является Buffer Cache, который интегрирован в способ доступа отдельных файловых систем к своим базовым устройствам хранения блоков.
Лекции по видео в системах хранения, Флэш файловая система p >
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);
}
Безопасность (1 → 2 → 8 → 4 → 3 → ...)
"UNIX не был предназначен для того, чтобы не допустить, чтобы его пользователи делали глупые вещи, поскольку это также мешало бы им делать умные вещи". - Дуг Гвин
Никакая техника не работает, если она не используется. Этика меняется с технологией.
" F × S = k" произведение свободы и безопасности является постоянным. - Законы Нивена
Криптография составляет основу доверия в Интернете. Хакер использует элементы управления безопасностью как в техническом, так и в физическом или человеческом элементе. Защита ядра от других запущенных программ - это первый шаг на пути к безопасной и стабильной системе, но этого явно недостаточно: необходима определенная степень защиты между различными приложениями для пользователей. Exploits может настраивать локальные или удаленные службы.
"Вы не можете взломать свою судьбу, грубую силу... вам нужен черный ход, боковой канал в Жизнь". - Клайд Дсоуза
Компьютеры не решают проблемы, они выполняют решения. За каждым недетерминированным алгоритмическим кодом существует определенный ум. -/var/log/dmesg
Лекции по видео по криптографии и сетевой безопасности, Пространства имен для безопасности, Защита от удаленных атак, Secure Embedded Linux
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
Источник ядра (0.11 → 2.4 → 2.6 → 3.18)
"Как вино, владение программным обеспечением ядра созревает со временем, но, в отличие от вина, оно становится все слаще". --Lawrence Mucheka
Возможно, вы не думаете, что программисты - это художники, но программирование - чрезвычайно творческая профессия. Это логическое творчество. Образование в области компьютерных наук не может сделать кого-либо экспертом-программистом больше, чем изучение кистей и пигмента может сделать кого-то экспертом-живописцем. Как вы уже знаете, есть разница между знанием пути и хождением по пути; крайне важно свернуть рукава и запотевать руки с исходным кодом ядра. Наконец, с приобретенным таким образом знанием ядра, куда бы вы ни отправились, вы будете сиять.
Незрелые кодеры имитируют; зрелые кодеры воруют; плохие кодеры декают то, что они берут, и хорошие кодеры делают это чем-то лучше или, по крайней мере, чем-то другим. Хороший кодер сваривает кражу во всем чувстве, которое уникально, совершенно отличное от того, из которого оно было порвано.
Лекции по видео в кулинарных рецептах
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/*
Отъезд Проект Janitor Языка Linux
'' Мы просматриваем исходный код ядра Linux, делаем обзоры кода, исправляем неподдерживаемый код и делаем другие очистки и конверсии API. Это хорошее начало взлома ядра. '
Я бы сказал: "Учись С".:)
Попробуйте эту бесплатную онлайн-книгу.
Руководство по программированию модуля ядра Linux http://www.linuxhq.com/guides/LKMPG/mpg.html
Следующие книги я прочитал и нашел очень полезным:
Проверить kernelnewbies.org, подписаться на список рассылки Kernelnewbies, попасть в irc.oftc.org #kernelnewbies
Некоторые ресурсы: