Linux-0.11
Курс теории: https://www.bilibili.com/video/bv1d4411v7u7
Полезные ссылки ( Linux-0.11 Комментарий): https://github.com/beride/linux0.11-1
Основной ветвь -исходный код Linux-0.11
Просмотреть различие кода: запрос выберите соответствующую ветвь и сравните ее с Main
✔ LAB0 Операционная система загрузки (Frank Lab0)
Переписать Bootsect.s в основном завершает следующие функции:
- Bootsect.s может распечатать сообщение «xxx загружается ...» на экране.
Перезапись настройки. В основном завершает следующие функции:
- Bootsect.s может завершить загрузку setup.s и прыгнуть на настройку. S Запустить адрес выполнения. и Setup.s выводит линию «Теперь мы находимся в настройке» на экране. SETUP.S может получить хотя бы один базовый аппаратный параметр (например, параметры памяти, параметры графических карт, параметры жесткого диска и т. Д.), Сохранять его в определенном адресе в памяти и выводить на экран. Setup.s больше не загружает ядро Linux, просто сохраняйте вышеуказанную информацию, отображаемую на экране.
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/568/document/
✔ LAB1 реализует системные вызовы (Branch Lab1)
- Общее количество системных вызовов, измененных в ядре/System_call.S, составляет 74.
- Добавьте макрос в include/unistd.h, чтобы указать позиционирование таблицы функций вызова.
- Напишите две функции (sys_iam, sys_whoami) Определения функций include/linux/sys.h. И добавить две новые функции в таблицу функций после этого.
- Добавлено ядро/who.c для реализации двух системных вызовов.
- Изменить Makefile
- Objs увеличивает, кто зависимость (кто. O)
- Добавить условия генерации зависимостей для Who.S и WHO.O в зависимости
- Сделайте Execute ./run, чтобы войти в подсистему Linux, и добавьте макро -определения IAM и WHOMI в /ср/Innclude/UNISTD.H (так же, как и точка 2).
- Написание тестовой программы в тестировании состояния пользователя, успешным.
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/569/document/
✔ Lab2 реализует отслеживание траектории работы процесса (Branch Lab2)
- Process.c реализует сценарий, который имитирует гибридные вычисления ЦП и вычисления ввода-вывода, и запускает его многопроцессным способом.
- Распечатайте несколько состояний переключения процесса ядра (время состояния PID) на /var/process.log.
- После функции init () в init/main входит в оператор состояния пользователя, ассоциируйте дескриптор файла 3 до /var/process.log.
- Реализуйте функцию fprintk () в ядре/printk, чтобы распечатать вывод в журнал process.log.
- Найдите точку переключения состояния и добавьте fprintk (), чтобы записать журналы.
- Запуск процесса ядра/system_call.s -> sys_fork (call copy_process)
- Запустить, блокировать ядро переключателя состояния/chade.c -> Расписание sys_pause sleep_on rtertive_sleep_on wake_up
- Exit kernel/exit.c -> do_exit sys_waitpid
- Примечание: GCC в Linux-0.11 не может быть составлен // прокомментирован.
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/570/document/
✔ Lab3 заменяет исходный процесс TSS в Linux0.11 для переключения на переключение стека (Bency Lab3)
Оригинальный метод переключения через TSS, который эквивалентен снижению реестра. Он напрямую заменяется на месте через инструкции, предоставленные Intel, которая медленнее. Переключение стека более эффективно.
ядро/sched.c
- Оригинальный метод switch_to основан на коммутаторе TSS, и мы хотим прокомментировать его в файле заголовка.
- New Switch_to, требуется два параметра (1: указатель на следующую печатную плату 2: положение следующей задачи в массиве используется для переключения LDT).
ядро/System_call.s
- Write switch_to АБСМЮСКА
- Переключение печатной платы
- Перепишите положение стека ядра TSS (в настоящее время TSS сохраняется, но в мире есть только один TSS, и он не используется для переключения процессов.)
- Переключить стек ядра
- Переключатель LDT
ядро/вика
- Войдите из настройки TSS в печатной плате.
- Добавьте новую переменную элемента - стек ядра в PCB, которая используется для хранения информации о стеке ядра.
- Запишите информацию о стеке здесь и позвольте PCB переменную члена точки на указатель.
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/571/document/
Ссылка: https://blog.csdn.net/qq_42518941/article/details/119182097
✔ Lab4 реализует Semaphore System Calls в Linux0.11 (Branch Lab4)
Предварительные знания
- Ядро/ched.c Sleep_on пройдите входящий заголовок очереди ожидания, установите ток в состояние блокировки и активно выполнять график (). TMP сохраняет оригинальную очередь блокировки. При пробуждении очереди блокировки все готовы к запуску.
- Ядро/ched.c Wake_up разбудит все заблокированные печатные платы. Только руководитель команды Wake-Up можно увидеть в программе, но это должно быть прочитано в сочетании со Sleep_on. После объединения вы обнаружите, что впоследствии просыпается голова пробуждения.
Напишите приложение «Pc.c», чтобы решить классическую проблему продюсера-потребителя и выполнить следующие функции:
- Установить процесс производителя, n потребительских процессов (n> 1)
- Создайте общий буфер с файлами
- Процесс продюсера записывает целые числа 0, 1, 2,…, M, M> = 500 в буфере, в свою очередь
- Потребительский процесс считывается из буфера, считывает по одному и удаляет числа чтения из буфера, а затем выводит идентификатор процесса и + номера в стандартный выход
- Буфер может сэкономить только до 10 чисел одновременно
Реализовать семафор
sem_t * sem_open ( const char * name , unsigned int value );
int sem_wait ( sem_t * sem );
int sem_post ( sem_t * sem );
int sem_unlink ( const char * name );
- sem_open открывает семафор
- Если семафор в настоящее время равен нулю, блокируя процесс
- Добавьте один семафор
- Выключить семафор
Фокус ожидания и публикации
- ждать
- Позвоните ядра/chade.c sleep_on, чтобы подождать блокировку
- Используйте прерывание Linux (Single Core Single Core) для защиты критической зоны Linux0.11
- минус одно значение SEM
- почта
- Добавьте один к значению SEM. Если значение больше 0, вызовите ядро/chade.c Wake_up, чтобы разбудить процесс, заблокированный этим семафором.
- Используйте прерывание Linux (Single Core Single Core) для защиты критической зоны Linux0.11
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/572/document/
✔ Картирование и обмен адресами LAB5 (Branch Lab5)
Логический адрес -> GDT -> LDT -> Таблица страницы -> Физический адрес
Теория инструментов знание
Сегментный селектор
Доступ к глобальной таблице дескрипторов с помощью GDTR осуществляется через «Сегментный селектор» (регистр сегмента в реальном режиме)
15 3 2 1 0
| Индекс | | Rpl |
- 3-15 является индексом дескрипторов, который указывает дескриптор требуемого сегмента в таблице дескрипторов.
- 2, чтобы указать, выбирается ли селектор в GDT или в LDT (0 представляет GDT 1 представляет LDT).
- 0-1-это уровень привилегий для выбора.
Сегментный селектор включает в себя три части: индекс дескриптора (индекс), TI и уровень привилегий запроса (RPL). Часть его индекса (индекс дескриптора) указывает дескриптор требуемого сегмента в положении таблицы дескриптора. Из этой позиции соответствующий дескриптор может быть найден на основе базового адреса таблицы дескрипторов, хранящегося в GDTR. Затем базовый адрес сегмента в таблице дескрипторов плюс логический адрес (sel: offset) может быть преобразован в линейный адрес. Значение TI в селекторе сегмента составляет всего один 0 или 1. 0 означает, что селектор выбирается в GDT, а 1 означает, что селектор выбирается в LDT. Уровень привилегий запроса (RPL) представляет уровень привилегий селектора, и существует 4 уровня привилегий (уровень 0, уровень 1, уровень 2 и уровень 3).
Примечание на уровне привилегий: каждый сегмент в задаче имеет определенный уровень. Всякий раз, когда программа пытается получить доступ к сегменту, уровень привилегий, к которому имеет программу, сравнивается с доступом к уровню привилегий, чтобы определить, можно ли получить доступ к сегменту. Системное соглашение заключается в том, что ЦП может получить доступ только к сегментам того же уровня привилегий или на более низком уровне привилегий.
Например, дайте логический адрес: 21H: 12345678H преобразован в линейный адрес
а Селектор SEL = 21H = 000000000000100 0 01 (b) означает: индекс селектора = 4, то есть 0100, и выбран четвертый дескриптор в GDT; Ti = 0 означает, что селектор выбирается в GDT; Последний 01 означает уровень привилегий RPL = 1.
беременный Offset = 12345678H Если базовый адрес сегмента, описанный в четвертом дескрипторе GDT в это время, составляет 1111111H, то линейный адрес = 1111111H + 12345678H = 23456789H.
Посетите GDT
- Сначала получите базовый адрес GDT из регистра GDTR.
- Затем в GDT дескриптор сегмента оценивается в 13-разрядном индексе положения сегмента.
- Получите базовый адрес, добавьте смещение, чтобы получить линейный адрес.
Доступ к LDT
- Сначала получите базовый адрес GDT из регистра GDTR.
- Получить индекс позиции сегмента, где LDT расположен от регистра LDTR (LDTR на 13 бит выше).
- Дескриптор сегмента LDT получается в GDT с этим индексом положения для получения базового адреса сегмента LDT.
- Используйте сегментный селектор, чтобы получить дескриптор сегмента из сегмента LDT.
- Получите базовый адрес, добавьте смещение, чтобы получить линейный адрес.
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/573/document/
✔ Управление устройством терминала Lab6 (ветвя Lab6)
- Когда происходит прерывание клавиатуры, код сканирования клавиатуры удаляется, а код сканирования обрабатывается в соответствии с таблицей Key_Table.
- Завершите написание функции для ключа F12.
- После обработки поместите символы с соответствующим кодом сканирования в put_queue.
- Вызовите do_tty_interrupt для окончательной обработки, где copy_to_cooked выполняет окончательную предварительную обработку, а затем вызовите con_write для вывода на графическую карту.
- write -> sys_write -> tty_write -> con_write.
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/574/document/
✔ Реализация файловой системы Lab7 Proc (Branch Lab7)
Теоретические знания
диск
Чтение и написание механических дисков требуют трех параметров для поиска
- Цилиндр (с)
- Голова (h)
- Сектор (ы)
block = C * ( H * S ) + H * S + S ;
Разделение нескольких секторов на один блок для повышения эффективности диска (Linux0.11 Разделение 2 секторов на один блок). Для более высокого уровня вам нужно только ввести номер блока чтения и записи для выполнения диска IO.
Разделение: Блок загрузки | Супер блок | INODE BITMAP | Data Bitmap | inode Block | Блок данных
документ
Используйте FCB (inode in linux0.11) для хранения информации о файле, включая различные типы файлов (например: файлы устройств, файлы каталогов ...).
struct m_inode
{
unsigned short i_mode ; // 文件类型和属性(rwx 位)。
unsigned short i_uid ; // 用户id(文件拥有者标识符)。
unsigned long i_size ; // 文件大小(字节数)。
unsigned long i_mtime ; // 修改时间(自1970.1.1:0 算起,秒)。
unsigned char i_gid ; // 组id(文件拥有者所在的组)。
unsigned char i_nlinks ; // 文件目录项链接数。
unsigned short i_zone [ 9 ]; // 直接(0-6)、间接(7)或双重间接(8)逻辑块号。
/* these are in memory also */
struct task_struct * i_wait ; // 等待该i 节点的进程。
unsigned long i_atime ; // 最后访问时间。
unsigned long i_ctime ; // i 节点自身修改时间。
unsigned short i_dev ; // i 节点所在的设备号。
unsigned short i_num ; // i 节点号。
unsigned short i_count ; // i 节点被使用的次数,0 表示该i 节点空闲。
unsigned char i_lock ; // 锁定标志。
unsigned char i_dirt ; // 已修改(脏)标志。
unsigned char i_pipe ; // 管道标志。
unsigned char i_mount ; // 安装标志。
unsigned char i_seek ; // 搜寻标志(lseek 时)。
unsigned char i_update ; // 更新标志。
}; Номер блока файла на диске хранится в INODE и в некоторой другой информации о описании файла. Там может быть несколько уровней руководства по позиции дискового блока, которые делятся на прямой индекс и косвенного индекса для получения позиции блока.
Оглавление
Найдите данные в соответствующем номере блока диска данных в соответствии с INODE Directory, который содержит номер блока диска INODE в подкаталоге, который существует в каталоге. Поиск слоя по слою, и вы можете найти местоположение конечного целевого каталога.
Экспериментальная учебная книга: https://www.lanqiao.cn/courses/115/labs/575/document/