Обучение программированию ядра

Я хочу изучить Linux-программирование ядра.

Что послужило бы отправной точкой для этого? Каковы могут быть некоторые из более простых проблем?

заблаговременно

Ответ 1

Попытайтесь заполучить книгу Роберта Люка по программированию ядра Linux. Его очень кратким и легко следовать.

После этого или вместе с этим вы можете взглянуть на "Понимание ядра Linux". Но я бы не рекомендовал его на ранних этапах.

Кроме того, посмотрите руководство по программированию ядра Linux. Поскольку многое может быть изучено при программировании модулей ядра, это руководство поможет вам. И да, для получения большой информации, обратитесь к подкаталогу "документации" в архиве источников ядра.

Ответ 2

**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 для теста на первичность:

Solovay Strassen Derandomized Algorithm for Primality Test

Читайте, чтобы не противоречить и не допускать; ни верить, ни считать само собой разумеющимся; ни найти разговоры и речи; но взвешивать и учитывать. Некоторые книги нужно пробовать, другие усвоить, а некоторые из них нужно пережевывать и переваривать: то есть некоторые книги должны читаться только по частям, другие - для чтения, но не любопытно, а некоторые из них должны быть прочитаны полностью, и с усердием и вниманием.

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 0.11 source (менее 20 000 строк исходного кода). После 20 лет разработки, по сравнению с Linux 0.11, Linux стал очень огромным, сложным и трудным для изучения. Но концепция дизайна и основная структура не имеют фундаментальных изменений. Изучение Linux 0.11 все еще имеет важное практическое значение.
  • Обязательное чтение для хакеров Hackers = > Linux_source_dir/Documentation/*
  • Вы должны быть подписаны и активны по крайней мере в одном списке рассылки ядра. Начните с ядро ​​newbies.
  • Вам не нужно читать полный исходный код. После того, как вы знакомы с API-интерфейсом ядра и его использованием, сразу начинайте с исходного кода интересующей вас подсистемы. Вы также можете начать с написания собственных модулей plug-n-play для экспериментов с ядром.
  • Авторы драйверов устройств выиграют от наличия собственного специализированного оборудования. Начните с Малины Пи.

Ответ 3

Отъезд Проект Janitor Языка Linux

'' Мы просматриваем исходный код ядра Linux, делаем обзоры кода, исправляем неподдерживаемый код и делаем другие очистки и конверсии API. Это хорошее начало взлома ядра. '

Ответ 4

Я бы сказал: "Учись С".:)

Попробуйте эту бесплатную онлайн-книгу.

Руководство по программированию модуля ядра Linux http://www.linuxhq.com/guides/LKMPG/mpg.html

Ответ 5

Следующие книги я прочитал и нашел очень полезным:

Ответ 6

Проверить kernelnewbies.org, подписаться на список рассылки Kernelnewbies, попасть в irc.oftc.org #kernelnewbies

Ответ 7

Некоторые ресурсы:

  • Книга: Роберт Любовь, Linux Kernel Development, 3-е издание.
  • Книга: Corbet, Rubini, драйверы устройств Linux, 3-е издание (бесплатная версия здесь)
  • Книга: ядро ​​Linux в двух словах (бесплатная версия здесь)
  • Свободный материал, предоставленный Свободные электроны