OSDev

для всех
Текущее время: 18 ноя 2018, 02:14

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




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
СообщениеДобавлено: 17 июн 2012, 09:40 

Зарегистрирован: 17 июн 2012, 09:26
Сообщения: 7
Здравствуйте, помогите, тут на днях начал пробовать реализовать многозадачность для своей ОС, но почему то при переключении задач перестают работать прерывания. То есть запускаю операционку - прерывания работают, создаю задачу. После этого сразу как срабатывает функция переключения задач - задача выполняется, но перестают работать прерывания, с чем может быть связанна проблема?
Структура задачи:
Код:
typedef struct task
{
   struct
   {
      struct TSS_t TSS;
      struct GDTgate_t LDT[2];
      int tssIdx;
      int ldtIdx;
      page_directory_t *page_directory;   // Page directory.
   }System;
   
   struct
   {
      int dynamic;
      int nice;
   }Priority;

   struct
   {
      u32int esp, ebp;         // Stack and base pointers.
      u32int eip;            // Instruction pointer.
      u32int kernel_stack;         // Kernel stack location.
   }Address;
   
   struct
   {
      struct task *next;         // The next task in a linked list.
      struct task *back;         // The back task in a linked list.
   }Link;
   
   char name[64];               //Name process
   enum status_t status;            //Status process
   int pid;               // Process ID.
} task_t;

Функция переключения задач:
Код:
void switch_task()
{
   if (!current_task)
      return;

   u32int esp, ebp, eip;
   asm volatile("mov %%esp, %0" : "=r"(esp));
   asm volatile("mov %%ebp, %0" : "=r"(ebp));

   eip = read_eip();

   // Have we just switched tasks?
   if (eip == 0x12345)
      return;

   // No, we didn't switch tasks. Let's save some register values and switch.
   current_task->Address.eip = eip;
   current_task->Address.esp = esp;
   current_task->Address.ebp = ebp;
   
   if (current_task->Link.next)
   {
      // Get the next task to run.
      current_task = current_task->Link.next;
      // If we fell off the end of the linked list start again at the beginning.
   }
   else
   {
      current_task = ready_queue;
   }

   eip = current_task->Address.eip;
   esp = current_task->Address.esp;
   ebp = current_task->Address.ebp;
   
   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_directory->physicalAddr));
}


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

Зарегистрирован: 22 май 2007, 15:29
Сообщения: 290
Как-то у вас оригинально переключение задач сделано. Весь код на одном и том же уровне привилегий работает, чтоль?


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

Зарегистрирован: 17 июн 2012, 09:26
Сообщения: 7
Да, пока что все выполняется на уровне ядра... Хотел после того как получится сделать нормально переключение задач реализовывать другие уровни привилегий.


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

Зарегистрирован: 17 июн 2012, 09:26
Сообщения: 7
Оригинально? Что ж, я в этом новичек, только на днях начал капать как это все устроенно...
Поэтому честно говоря пока что не представляю, как сделать это более оптимально.


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

Зарегистрирован: 22 май 2007, 15:29
Сообщения: 290
Выведите в задаче регистр eflags (через pushf/pop eax, например) и посмотрите, установлен ли флаг IF.

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


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

Зарегистрирован: 17 июн 2012, 09:26
Сообщения: 7
То есть вы предлагаете после переключения задач проверить флаг IF для задачи и если не установлен, то установить его? Я флаг не проверял, но после переключения задач пытался разрешить прерывания:
Код:
asm volatile("sti");
Не помогло.
Можете посоветовать какую-нибудь документацию по переключению уровней?


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

Зарегистрирован: 17 июн 2012, 09:26
Сообщения: 7
Сейчас проверил в задаче флаг IF после переключения, флаг установлен, но прерывания ни от таймера, ни от клавиатуры не проходят...


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

Зарегистрирован: 22 май 2007, 15:29
Сообщения: 290
Нет, я предлагал просто на состояние посмотреть.

А вы по таймеру переключаете? Если да, то посылается ли EOI контроллеру прерываний после переключения?


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

Зарегистрирован: 17 июн 2012, 09:26
Сообщения: 7
Да, по таймеру. Блин, да я забывал EOI контроллеру прерываний отсылать... Спасибо большое, все заработало!!! :D :lol:


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

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1197
Вообще EOI нужно посылать до переключения, а не после.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

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


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

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


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

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