Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

Исходники лежат тут

Немного усложним загрузчик : теперь будет поддерживать не один , а 2 процесса . Первый процесс назовем условно p1 , второй - p2 . Процесс p1 посылает процессу p2 пароль . Если пароль правильный , процесс p2 выводит на экран сообщение - "Yes".

В данном проекте используется принцип cooperative multitasking : если один процесс попадает в цикл , он пожирает все ресурсы , всё остальное при этом останавливается . Есть альтернатива - reemptive multitasking, - при этом ядро может принудительно переключать и управлять процессами . 2-й вариант реализовать конечно будет посложнее . В нашем загрузчике ядра-то собственно и нет - в данном контексте оно и не нужно .

В проекте используется единое адрессное пространство . Процеес p1 грузится по адресу 0x100000 - или 1 мегабайт - самое начало т.н. extended memory . Процесс p2 грузится по адресу 0x200000 . Адресное пространство между этими процессами не используется .

При линковке используется принцип relocation : линкеру явно указывается на прикручивание процессов p1 и p2 к соответствующим адресам :


 		$(V)$(LD) -e start -Ttext 0x100000 -Tdata 0x110000 -o $@ $^
Вообще , если глянуть в makefile , можно увидеть , что kernel.img лепится из 3-х слинкованных кусков :

 	boot
 	p1
 	p2
 
В свою очередь , boot линкуется из start.S + kernel.c

Структура образа kernel.img :

start.S + kernel.c) - загрузчик : хранится в первом секторе

Со 2-го по 33-й секторы хранится образ первого процесса p1

С 34 по 65 сектора хранится образ 2-го процесса p2

Формат - ELF

Порядок загрузки :

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

Выполняется код в start.S , устанавливается защищенный режим , инициализируется стек , запускается си-шный код bootmain() из kernel.c.

Загружаются в память образы 2-х процессов , и управление передается в первый процесс p1 .

Обоим процессам необходим свой стек : для процесса p1 он будет начинаться с адреса 0x200000 , для процесса p2 - с адреса 0x300000 .

Взаимодействуют процессы следующим образом : процесс p1 печатает пароль по одному символу в "pipe buffer" по адресу памяти PIPEBUF. После этого он ждет , когда p2 его прочитает , и печатает дальше. Функция _yield передает контроль от одного процесса к другому. ID-шник процесса - PROCESSID_P

Понятно , что никакой протекции здесь нет : процесс p1 преспокойно может прочитать пароль из адрессного пространства процесса p2 , может поменять его , может вообще поменять код у p2 , да и много чего еще .

В каталоге obj при компиляции генерятся файлы c расширением .sym - в них прописываются статические адреса функций - например p1.sym :


 00100000 T putch
 00100025 T start
 00100054 T _yield
 00100064 t _yield2
 00110000 A __bss_start
 00110000 A _edata
 00110000 A _end
 
Также там генерятся дизассемблированные файлы с расширением .asm .

PS: Загрузчик у меня работает только под бошем

Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье
Филипп
  Волшебные у Вас публикации! Мне доставляет нестерпимое наслаждение
знакомиться с ними. Есть несколько вопросов:
 А как передать управление процессу p1?
Смысл строки __asm __volatile("movl $0x1FFFFC, %esp; ret");
P.S. К сожалению у меня завелся только первый проект с hello word.
С уважением Филипп

2012-06-15 15:39:59
Яковлев Сергей
  Регистр esp используется для инициализации стека - мы отводим первому процессу в его же адресном
пространстве кусок памяти под собственные нужды.

Ядро, собираемое в этой статье, сделано с помощью хакерских технологий - тех же самых, с помощью
которых Линус собирал свои первые ядра. Я помню, что когда писал эту статью, то не смог его загрузить
ни в одном стандартном загрузчике.

 

2012-06-16 18:10:07
Филипп
  Здравствуйте, Сергей!
Можете ли Вы пояснить, как Вы передаете управление первому процессу p1?
В Вашем коде я вижу только чтение двух процессов с диска.
2012-06-20 11:43:21
Филипп
  Откуда Вы знаете на каких секторах хранится процессы p1 и p2?
Вы заливали на диск командой cat kernel.img > devsdc ?

2012-06-20 12:15:05