Изучение программирования ядра

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

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


person Geek    schedule 27.05.2009    source источник
comment
Этих вопросов и ответов достаточно, чтобы гарантировать полное игнорирование ярлыка [closed].   -  person Seamus    schedule 10.07.2021


Ответы (7)


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

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

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

person Community    schedule 27.05.2009

**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 заключается в преднамеренной запутанности кода, используемой вместе с ним. Это часто необходимо, чтобы передать вычислительный смысл, включающий две или более операций, чистым и элегантным способом. Это особенно актуально при написании кода для многоядерной архитектуры.

видеолекции по системам реального времени, Планирование задач, Сжатие памяти, Барьеры памяти, SMP

#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
  1. Разработка ядра LinuxРоберт Лав
  2. Понимание ядра Linux — Дэниел П. Бове, Марко Чезати
  3. Искусство проектирования ядра Linux – Ян Лисян
  4. Профессиональная архитектура ядра Linux — Вольфганг Мауэрер
  5. Проектирование операционной системы UNIX – Морис Дж. Бах
  6. Понимание диспетчера виртуальной памяти LinuxМел Горман
  7. Внутреннее устройство ядра LinuxТигран Айвазян
  8. Основы для встраиваемых систем LinuxКристофер Халлинан

Драйверы устройств Linux ( 1 -> 2 -> 4 -> 3 -> 8 -> ... )

"Музыка не увлекает вас за собой. Вы должны удерживать ее исключительно за счет своей способности действительно просто сосредоточиться на этом маленьком зернышке эмоции или истории". -- Дебби Гарри

Ваша задача в основном состоит в том, чтобы установить высокоскоростной интерфейс связи между аппаратным устройством и программным ядром. Вам следует прочитать справочное техническое описание/руководство по оборудованию, чтобы понять поведение устройства, его управление и состояние данных, а также предоставляемые физические каналы. Знание ассемблера для вашей конкретной архитектуры и хорошее знание языков описания оборудования СБИС, таких как VHDL или Verilog, помогут вам в долгосрочной перспективе.

В. Но зачем мне читать спецификации оборудования?

О: Потому что "существует пропасть между углеродом и кремнием, которую программное обеспечение не может преодолеть", – Рахул Соннад.

Однако это не создает проблемы для вычислительных алгоритмов (кода драйвера - обработка нижней половины), поскольку это может полностью смоделирована на универсальной машине Тьюринга. Если вычисленный результат верен в математической области, можно с уверенностью сказать, что это также верно в физическом домене.

Видео-лекции о драйверах устройств Linux (Lec . 17 и 18), Анатомия встроенного драйвера KMS, Контроль контактов и обновление 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;
}
  1. Драйверы устройств для LinuxДжонатан Корбет, Алессандро Рубини и Грег Кроа-Хартман
  2. Основные драйверы устройств LinuxСрикришнан Венкатешваран< /эм>
  3. Написание драйверов устройств LinuxДжерри Куперштейн< /эм>
  4. Руководство по программированию модуля ядра LinuxПитер Джей Зальцман, Майкл Буриан, Ори Померанц
  5. Руководство программиста Linux PCMCIAДэвид Хайндс
  6. Руководство по программированию SCSI в Linux - Хайко Эйбфельдт
  7. Руководство по серийному программированию для операционных систем POSIXМайкл Р. , Сладкий
  8. Графические драйверы Linux: введениеСтефан Маршезин
  9. Руководство по программированию драйверов USB-устройств для Linux - Детлеф Флигль
  10. Модель устройства ядра 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);
} 
  1. Понимание внутреннего устройства сети LinuxКристиан Бенвенути< /эм>
  2. Сеть ядра Linux: реализация и теория – Рами Розен
  3. Сетевое программирование UNIX — W. Ричард Стивенс
  4. Полное руководство по сетевому программированию в Linux – Кейр Дэвис, Джон У. Тернер, Натан Йоком
  5. Стек Linux TCP/IP: работа в сети для встроенных систем - Томас Ф. Герберт
  6. Программирование сокетов Linux на примере - Уоррен В. , Гей
  7. HOWTO по расширенной маршрутизации и управлению трафиком в Linux - Берт Хьюберт

Отладка ядра ( 1 -> 4 -> 9 -> ... )

Если при общении с ним человек не говорит точно, что имеет в виду, это неизбежно приведет к неприятностям. ~Алан Тьюринг, о компьютерах

Брайан В. Керниган в статье Unix для начинающих (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. Отладка Linux и настройка производительностиСтив Бест
  2. Методы отладки приложений Linux — Аурелиан Мелинте
  3. Отладка с помощью GDB: отладчик исходного кода GNU Роланд Х. Пеш
  4. Отладка встроенного LinuxКристофер Халлинан
  5. Искусство отладки с помощью GDB, DDD и Eclipse - Норман С. Мэтлофф
  6. Почему программы терпят неудачу: руководство по систематической отладке - < em>Андреас Зеллер
  7. Экзорцизм программного обеспечения: руководство по отладке и оптимизации устаревшего кода - Билл Бланден
  8. Отладка: выявление наиболее трудноуловимых проблем с программным и аппаратным обеспечением - < em>Дэвид Дж. Аганс
  9. Отладка с помощью размышлений: междисциплинарный подход – Роберт Чарльз Мецгер
  10. Найдите ошибку: Книга неверных программ - < em>Адам Барр

Файловые системы ( 1 -> 2 -> 6 -> ... )

"Я хотел иметь виртуальную память, по крайней мере, в сочетании с файловыми системами". -- Кен Томпсон

В системе UNIX все является файлом; если что-то не является файлом, это процесс, за исключением именованных каналов и сокетов. В файловой системе файл представлен inode, своего рода порядковым номером, содержащим информацию о фактических данных, из которых состоит файл. Виртуальная файловая система Linux VFS кэширует в памяти информацию из каждой файловой системы по мере ее монтирования и использования. Необходимо уделять много внимания правильному обновлению файловой системы, поскольку данные в этих кэшах изменяются по мере создания, записи и удаления файлов и каталогов. Наиболее важным из этих кэшей является буферный кэш, который интегрирован в способ, которым отдельные файловые системы обращаются к своим базовым блочным устройствам хранения.

Видео-лекции по системам хранения, Файловая система, поддерживающая 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);
}
  1. Файловые системы Linux — Моше Бар
  2. Файловые системы LinuxУильям фон Хаген
  3. Файловые системы UNIX: эволюция, проектирование и реализация - Стив Д. Пейт
  4. Практический проект файловой системыДоминик Джампаоло< /эм>
  5. Криминалистический анализ файловой системы – Брайан Кэрриер< /эм>
  6. Иерархия файловой системы Linux - Бин Нгуен
  7. BTRFS: файловая система B-tree Linux - Охад Роде
  8. 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"
  1. Взлом: искусство эксплуатацииДжон Эриксон
  2. Арсенал руткитов: побег и уклонение в темных уголках системы - Билл Бланден
  3. Разоблачение взлома: секреты сетевой безопасности – Стюарт МакКлюр, Джоэл Скамбрей, Джордж Курц
  4. Руководство по эксплуатации ядра: атака ядра - < em>Энрико Перла, Массимилиано Олдани
  5. Искусство криминалистики памяти — Майкл Хейл Лайт, Эндрю Кейс, Джейми Леви, Аарон Уолтерс
  6. Практический обратный инжинирингБрюс Данг, Александр Gazet, Элиас Бачалани
  7. Практический анализ вредоносных программМайкл Сикорский, Эндрю Хониг
  8. Максимальная безопасность Linux: руководство хакера по защите вашего сервера Linux - Анонимно
  9. Безопасность Linux — Крейг Хант
  10. Реальная безопасность LinuxБоб Токсен< /эм>

Исходный код ядра ( 0,11 -> 2,4 -> 2,6 -> 3,18 )

«Как и вино, мастерство программирования ядра со временем созревает. Но, в отличие от вина, в процессе оно становится слаще». -- Лоуренс Мучека

Вы можете не думать, что программисты — художники, но программирование — чрезвычайно творческая профессия. Это логическое творчество. Образование в области информатики не может сделать кого-либо опытным программистом, так же как изучение кистей и пигментов не может сделать кого-то опытным художником. Как вы уже знаете, есть разница между знанием пути и идущим по нему; Крайне важно засучить рукава и запачкать руки исходным кодом ядра. Наконец, с вашими таким образом полученными знаниями ядра, куда бы вы ни пошли, вы будете сиять.

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

Видео-лекции о рецептах ядра

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
  1. Начальный уровень с исходным кодом Linux 0.11 (менее 20 000 строк исходный код). После 20 лет разработки, по сравнению с Linux 0.11, Linux стал очень большим, сложным и трудным для изучения. Но концепция дизайна и основная структура не претерпели принципиальных изменений. Изучение Linux 0.11 по-прежнему имеет важное практическое значение.
  2. Обязательное чтение для хакеров ядра => Linux_source_dir/Documentation/*
  3. Вы должны быть подписаны и активны хотя бы в одном списке рассылки ядра. Начните с новичков в ядре.
  4. Вам не нужно читать весь исходный код. Как только вы ознакомитесь с API ядра и его использованием, начните непосредственно с исходного кода интересующей вас подсистемы. Вы также можете начать с написания собственных модулей plug-n-play для экспериментов с ядром.
  5. Разработчики драйверов устройств выиграют, если у них будет собственное выделенное оборудование. Начните с Raspberry Pi.
person manav m-n    schedule 05.01.2015
comment
Приятно видеть прочный, исчерпывающий и не зависящий от ссылок ответ на такой вопрос. +1 - person Rudi Kershaw; 08.01.2015
comment
@manav m-n: Можете ли вы сказать, почему вы публикуете Solovay–Strassen primality test в своем ответе. Я думаю, вы хотите что-то выразить, но я не понял. - person user565739; 02.07.2015
comment
Хакер не может, как они сокрушительно выразились, «подходить к решению проблем, как сантехник в хозяйственном магазине»; вы должны знать, что на самом деле делают компоненты. Этот код приложен в качестве примера к следующему абзацу... взвесить и рассмотреть... - person manav m-n; 02.07.2015

Ознакомьтесь с проектом Linux Kernel Janitor.

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

person John Smith    schedule 27.05.2009
comment
Для тех, кто хочет узнать больше о проекте The Linux Kernel Janitor Project, я написал свою магистерскую диссертацию, анализируя их работу. Этот отчет недавно опубликован в виде книги, ISBN 978-3-639-20637-1. bookfinder.com/search/ - person hlovdal; 24.11.2009

Я бы сказал: «изучайте C». :)

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

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

person Antonio Louro    schedule 27.05.2009


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

person Community    schedule 27.05.2009

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

  • Книга: Роберт Лав, Разработка ядра Linux, 3-е издание
  • Книга: Corbet, Rubini, драйверы устройств Linux, 3-е издание (бесплатная версия здесь)
  • Книга: Кратко о ядре Linux (бесплатная версия здесь)
  • Бесплатный материал предоставлен Free Electrons
person Claudio    schedule 31.10.2013