OSDev

для всех
Текущее время: 27 апр 2024, 18:13

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 36 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
СообщениеДобавлено: 25 июл 2013, 10:54 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
Привет сообществу!

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

Для представления выбрал последнюю публикацию о настройке полноценной среды разработки ОС на связке Eclipse + VMware + GDB. Может кому-то пригодится...

P.S.: Надо сказать с исходным источником есть ряд проблем, в частности с реализацией многозадачности описанной там...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 12:53 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Очень интересно, почитаю на досуге. Здесь один участник уже пишет Phantom, названия почти совпадают. А как расшифровывается Ex?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 13:29 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
Himik писал(а):
Здесь один участник уже пишет Phantom, названия почти совпадают. А как расшифровывается Ex?


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

Ex - это experimental, учебная операционная система для демонстрации методов построения ОС. Что-то типа лабораторных работ по основным аспектам.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 14:07 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
ЧЁ-то много фантомов развелось :D Поздравляю с достойным стартапом. Будем надеяться на такое же продолжение.

С тем, что пишущие под виндами - извращенцы, не согласен. Часть инструментария можно подтянуть из тех же никсов, часть написать самому. Отладка - это конечно хорошо, но на первых порах можно обойтись и без нее, а потом в случае необходимости уже использовать собственные отладочные средства.

Какие именно проблемы с реализацией многозадачности?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 15:09 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
phantom-84 писал(а):
С тем, что пишущие под виндами - извращенцы, не согласен


Ну конечно же нет, это я несколько погорячился, просто уже привык очевидной простоте многих инструментов используемых в *nix, и достаточно надуманной сложности тех же инструментов в win.

Насчет отладки, ну не скажите. До вчера довольствовался лишь самописным ASSERT-ом и выводом на экран каждого чиха, и было довольно тяжко. Есть виртуальная FS содранная у того же Molloy, но пока не использую, логов не веду. Так что отладка из среды в относительной динамике это подспорье

Насчет же многозадачности, James Molloy предлагает алгоритм на основе вызова fork() вида
Код:
/*-----------------------------------------------------------------------------
 *
 * --------------------------------------------------------------------------*/
int fork(void)
{
   int               pid = 0;
   volatile task_t*   parent_task;
   volatile task_t*   new_task;
   volatile task_t*   tmp_task;
   page_directory_t*   dir;
   u32int            eip;
   u32int            esp;
   u32int            ebp;

   print_text("Forking kernel task........................\n");

   /* Disable interrupts */
   asm volatile ("cli");

   /* Parent task is our current task */
   parent_task = (task_t*) current_task;

   /* Clone current page directory */
   dir = (page_directory_t*) clone_directory(current_dir);

   debug_msg("Page directory for new task addr = ", (u32int) dir->phys_addr);

   /* Create and initialize new task */
   new_task = (task_t*) kmalloc(sizeof(task_t));

   new_task->pid = next_pid++;
   new_task->esp = 0;
   new_task->ebp = 0;
   new_task->eip = 0;
   new_task->page_dir = dir;
   new_task->next = 0;

   /* Place new task to tail of queue */
   tmp_task = (task_t*) ready_queue;

   /* find tail of queue */
   while (tmp_task->next)
   {
      tmp_task = (task_t*) tmp_task->next;
   }

   tmp_task->next = (struct task_t*) new_task; /* place new task to tail */

   /* Get current EIP */
   eip = read_eip();

   /* Here we must been after task switch */

   if (current_task == parent_task)
   {
      /* We in parent task */
      asm volatile ("mov %%esp, %0":"=r"(esp));
      asm volatile ("mov %%ebp, %0":"=r"(ebp));

      new_task->esp = esp;
      new_task->ebp = ebp;
      new_task->eip = eip;

      asm volatile ("sti");

      return new_task->pid;
   }
   else
   {
      return 0;
   }
}


прототипа планировщика вида
Код:
/*-----------------------------------------------------------------------------
 *
 * --------------------------------------------------------------------------*/
void switch_task(void)
{
   u32int   esp;
   u32int   ebp;
   u32int   eip;

   /* If we have't task, then exit */
   if (!current_task)
      return;

   /* Read ESP and EBP registers */
   asm volatile ("mov %%esp, %0":"=r"(esp));
   asm volatile ("mov %%ebp, %0":"=r"(ebp));

   eip = read_eip();

   if (eip == 0x12345)
   {

      return;
   }

   /* Switch task */

   current_task->esp = esp;
   current_task->ebp = ebp;
   current_task->eip = eip;

   current_task = (task_t*) current_task->next;

   if (!current_task)
      current_task = ready_queue;

   esp = current_task->esp;
   ebp = current_task->ebp;
   eip = current_task->eip;



   current_dir = (page_directory_t*) current_task->page_dir;

   asm volatile ("\
   cli; \
   mov %0, %%ecx; \
   mov %1, %%esp; \
   mov %2,   %%ebp; \
   mov   %3,   %%cr3; \
   mov   $0x12345, %%eax; \
   sti; \
   jmp *%%ecx"
         ::"r"(eip),"r"(esp),"r"(ebp),"r"(current_dir->phys_addr));
}


где функция взятия значения EIP имеет вид
Код:
/*------------------------------------------------------------------------------
//      Function for read EIP
//----------------------------------------------------------------------------*/
.global read_eip

read_eip:
   
        pop     %eax
        jmp     *%eax


Причем дочерняя задача создается из основной, копируется директория страниц, но вот на этом участке, в родительском процессе
Код:
/* Get current EIP */
   eip = read_eip();

   /* Here we must been after task switch */

   if (current_task == parent_task)
   {
      /* We in parent task */
      asm volatile ("mov %%esp, %0":"=r"(esp));
      asm volatile ("mov %%ebp, %0":"=r"(ebp));

      new_task->esp = esp;
      new_task->ebp = ebp;
      new_task->eip = eip;

      asm volatile ("sti");

      return new_task->pid;
   }
   else
   {
      return 0;
   }


При возврате в fork() из "дочки" движение должно идти по ветке else, и оно идет, но управление потом передается на адрес в секции данных как раз где лежит current_task, помещенная в EAX при сравнении, и естественно в коде имеем исключение #UD, так как процессор пытается выполнить не родительскую задачу, а белеберду.

Код сопровождаемый вызовом fork() таков (функция main.c)
Код:
asm volatile ("sti");

init_timer(BASE_FREQ);

init_tasking();

ret = fork();

asm volatile ("cli");

if (ret == 0)
 print_text("Parent task!!!\n");
else
 print_text("New task\n!!!");

asm volatile ("sti");

return 0;


Данный код многократно и вдумчиво переписан, и вот возникает вопрос, что хороший в принципе мануал JM не работает на 9 главе... Или я что-то не понимаю до конца


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 16:47 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Я не знаю, как это может работать без использования независимых стеков для каждой задачи.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 16:55 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
phantom-84 писал(а):
Я не знаю, как это может работать без использования независимых стеков для каждой задачи.


Вот и я не знаю, собственно. В 10 главе, про переход в user mode, Molloy что-то там про стеки задач рассказывает, но я не разбирался ещё, в общем-то - уперся в то что в конце девятой главы приводится типо работающий пример.

Короче говоря, планировщик я буду писать сам, сейчас вплотную этим занят. А вот в мануале JM есть таки много противоречий и ошибок, и несоотвестствия с исходниками, стянутыми с svn, которые кстати не собираются даже после исправления явной ошибки task_switch() вместо switch_task() в обработчике IRQ0...

Эпично было еще то, что JM использует для пометки размещенных в физических фреймах страниц битовое поле frames, размер которого вычисляет как nframes/32 в байтах, где nframes = mem_size/PAGE_SIZE - максимальное число фреймов, mem_size - объем физической памяти, PAGE_SIZE = 0x1000 - размер страницы. Почему же, если одному биту соответствует одна размещенная в физ. памяти страница, то размер поля nframes/8 должен быть, в маллок размер выделяемой памяти идет в байтах а не в двойных словах... То-то у меня часто падала страничная память из-за нехватки фреймов :( при тестовой разметке всех возможных адресов. Ещё бы если битов во frames в 4 раза меньше чем надо. Пока это не исправил, не подумал, и почти что с нуля не переписал этот урок, ничего не заработало.


Последний раз редактировалось maisvendoo 25 июл 2013, 17:12, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 17:07 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Попробуй мой вариант использования стеков ядра. Он идеально подходит для переключения между kernel mode и user mode. Суть в том, чтобы стек ядра размещать непосредственно перед структурой задачи (и распределять этот участок за один шаг). Тогда указатель на структуру задачи будет одновременно являться и указателем на вершину стека ядра для этой задачи. В этом случае можно совместить переменную current с TSS.esp0.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 17:11 
Аватара пользователя

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
phantom-84 писал(а):
Попробуй мой вариант использования стеков ядра

попробую :)

P.S.: Да, и поправлю я про разработку под виндой, а то мне что-то стыдно стало...
P.P.S.: поправил


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 25 июл 2013, 17:25 

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
maisvendoo писал(а):
Короче говоря, планировщик я буду писать сам, сейчас вплотную этим занят. А вот в мануале JM есть таки много противоречий и ошибок, и несоотвестствия с исходниками, стянутыми с svn, которые кстати не собираются даже после исправления явной ошибки task_switch() вместо switch_task() в обработчике IRQ0...
Для учебной модели пойдет. Только мне не нравится, что нужно искать конец очереди (при добавлении новой структуры). Нужно ввести указатель на конец очереди, а еще лучше использовать кольцевую очередь. Еще мне сильно не понравилось, что завершение переключения находится в середине switch_task. Есть намного более элегантный способ это сделать.

Цитата:
Эпично было еще то, что JM использует для пометки размещенных в физических фреймах страниц битовое поле frames, размер которого вычисляет как nframes/32 в байтах, где nframes = mem_size/PAGE_SIZE - максимальное число фреймов, mem_size - объем физической памяти, PAGE_SIZE = 0x1000 - размер страницы. Почему же, если одному биту соответствует одна размещенная в физ. памяти страница, то размер поля nframes/8 должен быть, в маллок размер выделяемой памяти идет в байтах а не в двойных словах... То-то у меня часто падала страничная память из-за нехватки фреймов :( при тестовой разметке всех возможных адресов. Ещё бы если битов во frames в 4 раза меньше чем надо. Пока это не исправил, не подумал, и почти что с нуля не переписал этот урок, ничего не заработало.
Как по мне, использовать код из подобных обучалок - себя не уважать. Можно опираться на него в том случае, если заложенный в нем алгоритм вас полностью устраивает, но писать самому.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 36 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB