Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 OS
 osjournal 
 Protected Mode 
 Hardware 
 Kernels
  Dark Fiber
  BOS
  QNX
  OS Dev
  Lecture notes
  MINIX
  OS
  Solaris
  История UNIX
  История FreeBSD
  Сетунь
  Эльбрус
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Part 4...2318 
 Linux Kernel 2.6...1766 
 Go Web ...1752 
 Linux Inline for x86...1751 
 William Gropp...1750 
 Ext4 FS...1750 
 uOS...1750 
 Assembler...1749 
 NASM...1749 
 M.Marcu...1749 
 Ext2 internals...1749 
 Part 1...1749 
 AT&T Tutorial...1749 
 FAQ...1748 
 Stevens-> Глава 4...1748 
 ffmpeg->tutorial...1748 
 File handling...1748 
 Trees...1748 
 OS-FAQ 2...1748 
 Redis...1748 
 
  01.01.2024 : 3621733 посещений 

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