Игрушечная ОС, 32 -битная, наконец, реализует простую интерактивную оболочку 
Список дел:
Всего существует два жестких диска, сама система установлена на основном диске, и используется режим загрузки MBR, и используется процесс MBR-> загрузочного погрузчика.> Керннел.
MBR расположен в 1 секторе, начиная LBA 0号扇区
Boot Loader расположен в 4 секторах, начиная с LBA 2号扇区
Kernel расположено в пределах 200 секторов, начиная с диска LBA 9号扇区
Файловая система реализована на рабском диске. Это может быть не очень разумным. Если файловая система основана на логике коммерческой системы, она должна быть реализована сейчас, а затем операционная система установлена в соответствующем разделе.
Петчанка памяти, одна страница 4 кб
Управление памятью использует управление растровым растровом и различается по размеру при распределении памяти. Если он больше 1024 байт, он выделяется непосредственно по странице.
Если это меньше 1024 байтов, на основе распределения арены по странице используйте блокчейн на холостом ходу на арене для распределения и контроля.
Для удобства, хотя механизм пейджинга включен, функция переключения страниц памяти и дисков не реализована.

PCB - это 1 страница размер
Основная сущность планирования потоков заключается в переключении платы, управляя переключением указателя ESP путем часового прерывания. Приоритет отражается в длине пореза времени выполнения каждой резьбы.
Реализация процесса основана на потоках, а выбор TSS основан на Linux, используя отдельные TSS для резервного уровня 0 стеков 0 и указателей стека уровня 0. Самое большое отличие от потока заключается в том, что в процессе есть адрес таблицы страниц в печатной плате, что является самой большой разницей между процессом и потоком. Процесс действительно имеет свое независимое пространство виртуальной памяти.
В планировании нет эффективного алгоритма, просто используйте планирование петли очередей
Реализация потока простаивания
Реализация потока холостого хода очень проста. Когда в первый раз вы получите график, вы блокируете его и отдаете его из процессора. Когда планировщик снова выполняет отправку, если в очереди на готовой поток не будет обнаружено готового потока или процесса, поток холостого хода будет пробужден. В настоящее время нить холостого хода подвекает процессор через hlt . Когда срез времени используется, а процессор не обнаружил готового процесса или потока, продолжайте заменить поток холостого хода на процессор. В настоящее время холостое время продолжит блокировать себя, а затем начнет повторять вышеупомянутый процесс планирования.
// 空载任务
static void idle ( void * arg ) {
while ( 1 ) {
thread_block ( TASK_BLOCKED );
asm volatile ( "sti; hlt" : : : "memory" );
}
}Процесс вилка
Форк процесса сначала скопирует печатную плату текущего процесса, а затем создайте новую таблицу страниц через растровую карту виртуального пула текущего процесса. Переписка виртуального адреса точно такой же, как в исходном процессе. Наконец, сайт прерывания подделывается, и дочерний процесс добавляется в очередь планирования и ожидает выполнения планирования. На сайте кованого прерывания EAX в печатной плате дочернего процесса модифицируется на 0, что означает, что возвратное значение вилки составляет 0 в новом процессе, в то время как EAX в PCB родительского процесса остается неизменным, представляя PID детского процесса. Родительский процесс возвращается через конец системного вызова, в то время как дочерний процесс возвращается непосредственно через функцию выхода прерывания.
Процесс Exec
Реализация EXEC сначала загружает файл ELF с диска в память, затем изменяет имя процесса в печатной плате текущего процесса и помещает параметры, требуемые процессом, который должен быть выполнен в согласованный регистр, и изменяет EIP в точку входа в ELF, подделка сайта интерфейса, и выполняет новый процесс непосредственно, вызывая непосредственную выпуск функции Intremit Intr_exit.
Среди них точка входа ELF реализована путем реализации самой простой CRT, которая дает _Start вступитель и выдвигает согласованные регистры параметров в стек 3-уровневого и вызывает основную функцию внешней команды, чтобы реализовать передачу параметров.
[bits 32]
extern main
extern exit
; 这是一个简易版的CRT
; 如果链接时候ld不指定-e main的话,那ld默认会使用_start来充当入口
; 这里的_start的简陋实现,充当了exec调用的进程从伪造的中断中返回时的入口地址
; 通过这个_start, 压入了在execv中存放用户进程参数的两个寄存器。然后call 用户进程main来实现了向用户进程传递参数
section .text
global _start
_start:
;下面这两个要和 execv 中 load 之后指定的寄存器一致
push ebx ;压入 argv
push ecx ;压入 argc
call main
; 压入main的返回值
push eax
call exit ; 不再返回,直接调度别的进程了,这个进程直接被回收了Процесс ожидание
После вилки и выполнения локальной команды, чтобы не появиться, родительский процесс должен закончиться в местном дочернем процессе ожидания.
Реализация здесь заключается в том, чтобы ввести системный вызов SYS_WAIT, пройти всю очередь процесса, найти процесс, родительский процесс которого является его собственным приостановленным состоянием, а затем получить возвратное значение в его печатной плате, переработать таблицы PCB и каталог PAGE и удалите его из очереди планирования. Если после обхода не найдено никакого ожидающего дочернего процесса, заблокируйте себя и дождитесь просыпания дочернего процесса.
Выход процесса
Во время выполнения внешние команды фактически обернуты простым ЭЛТ, созданным самим собой. Основной из простой внешней команды CRT -вызова получит свое возвращаемое значение в конце, передайте ее в выход, а затем вызовите выход
Реализация здесь в основном делает три вещи:
Весь процесс загрузки внешних команд и их выполнения
Во -первых, внешняя команда должна обеспечить функцию int main(int argc, char **argv) . При связывании вам необходимо донести самодельный простой start.o CRT.O и, наконец, написать скомпилированные внешние команды в файловую систему.
Когда должна быть выполнена внешняя команда, текущий процесс разбивает процесс, execv в новом процессе, текущий процесс выполняет ожидание, передает адрес, чтобы принять возвратное значение дочернего процесса, а затем блокирует и ожидает возврата нового процесса. The new process loads external commands from the file system to memory in exevc, and changes the relevant content in pcb to the information of external commands, and modifies the eip in the pcb interrupt stack to the CRT's _start entry (at this time the new process has completely replaced itself with the external command process to be executed), and finally uses the interrupt exit function intr_exit to fake the interrupt exit and enter the CRT and then enter the main of the external командование Когда основное выполнение внешней команды заканчивается и возвращается, вызывает вызовы CRT через основное возвратное значение, поместите основное возвращаемое значение в sys_exit в соответствующую позицию процесса PCB, перерабатывают все ресурсы, кроме таблицы PCB и Page Directory, а затем разбудите родительский процесс и блокируют дочерний процесс. После того, как родительский процесс пробуждается, системный вызов sys_wait получает возвратное значение от печатной платы печатной платы печатной платы печатной платы печатной платы печатной платы печатной платы на рассылках печатной платы на печатной плате от печатной платы, очищает таблицу рассылки страниц на печатном процессе, возвращается в процесс ребенка, и возвращается в процесс для детей, и возвращается в процесс для детей, и возвращается в пенс. На этом этапе детский процесс был выполнен и полностью переработан.
Реализация файловой системы имитирует inode of Unix, подобные системам
Разделение ограничивает количество INODES 4096. ЦП эксплуатирует жесткий диск в соответствии с размером блока (кластер), а один блок устанавливается в сектор с 512 байтами.
INODE поддерживает 12 прямых блоков и 1 первого непрямого таблицы. Один блок составляет 512 байт в секторе, поэтому один файл поддерживает до 140 * 512 байтов.
структура INODE

Макет файловой системы

Соответствие между дескриптором файла и inode

Реализация трубопровода зависит от структуры файла в файловой системе. Его сущность состоит в том, чтобы заменить iNode, что структура файла должна изначально соответствовать кольцевому буферному пространству в пространстве ядра.
// 因为管道也是当作文件来对待,因此file结构体在针对真实文件和管道是有不同的意义
struct file {
// 文件操作的偏移指针, 当是管道是表示管道打开的次数
uint32_t fd_pos ;
// 文件的操作标志,当是管道是一个固定值0xFFFF
uint32_t fd_flag ;
// 对应的inode指针,当是管道时指向管道的环形缓冲区
struct inode * fd_inode ;
}; Поскольку пространство ядра разделяется, связь между различными процессами может быть достигнута с помощью конвейеров для чтения и записи. Чтение и запись трубопровода инкапсулируется в sys_write и sys_read , поэтому нет никакой разницы между работой трубопроводом и работой обычные файлы.
Суть перенаправления состоит в том, чтобы изменить адрес соответствующей таблицы глобальных дескрипторов в таблице дескрипторов PCB, а затем операция чтения и записи соответствующего дескриптора файла указывается на новый файл.
Реализация символа трубопровода | В оболочке достигается перенаправление стандартного входа и стандартного выхода на трубопровод.
int32_t sys_read ( int32_t fd , void * buf , uint32_t count ) {
if ( fd == stdin_no ) {
if ( is_pipe ( fd )) {
// 从已经重定向好管道中读
ret = pipe_read ( fd , buf , count );
} else {
// 从键盘获取输入
}
} else if ( is_pipe ( fd )) {
// 读管道
ret = pipe_read ( fd , buf , count );
} else {
// 读取普通文件
}
return ret ;
}
int32_t sys_write ( int32_t fd , const void * buf , uint32_t count ) {
if ( fd == stdout_no ) {
if ( is_pipe ( fd )) {
// 向已经重定向好管道中写入
return pipe_write ( fd , buf , count );
} else {
// 向控制台输出内容
}
} else if ( is_pipe ( fd )) {
// 写管道
return pipe_write ( fd , buf , count );
} else {
// 向普通文件写入
}
}