OSDev

для всех
Текущее время: 28 апр 2024, 00:38

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




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

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

Вот это?
Код:
if (eip == 0x12345)
{
   return;
}

phantom-84 писал(а):
Есть намного более элегантный способ это сделать.

А какой?


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

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Хранить адрес "возобновления" в стеке, а не в структуре задачи. Посмотри мой упрощенный пример здесь. Кстати если switch_task вызывается только в обработчике, то адрес "возобновления" может быть сохранен/восстановлен автоматически, т.е. для switch_task даже отдельную функцию можно не делать.


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

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

О, спасибо, буду разбираться :)


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

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
phantom-84 писал(а):
Я не знаю, как это может работать без использования независимых стеков для каждой задачи.

Просто каждая задача работает в отдельном адресном пространстве. Функция clone_directory не просто копирует таблицы страниц, но и содержимое физической памяти. Если это не так, либо у maisvendoo вместо этого пустая заглушка, то работать не будет.


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

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Копировать всю физ. память очень неэффективно. User space можно отдать на откуп механизму copy-on-write, глобальную память ядра оставить в одном экземпляре, а стек ядра (по крайней мере актуальные данные между esp и вершиной стека) и др. локальные данные ядра продублировать.


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

Зарегистрирован: 25 июл 2013, 08:45
Сообщения: 141
Откуда: Новочеркасск
Himik писал(а):
Функция clone_directory не просто копирует таблицы страниц, но и содержимое физической памяти. Если это не так, либо у maisvendoo вместо этого пустая заглушка, то работать не будет.

Реализовано копирование физической памяти, да, происходит переключение в режим с сегментной адресацией, потом копирование страниц, потом возврат обратно в страничную адресацию
Код:
/*------------------------------------------------------------------------------
//      Copy data from page (in physical memory!)
//----------------------------------------------------------------------------*/
.global     copy_page_physical

copy_page_physical:

        /* Push EBX and EFLAGS */
        push    %ebx
        pushf

        /* Switch off all interrupts */
        cli

        /* Get parametrs from stack */
        mov     12(%esp), %ebx
        mov     16(%esp), %ecx

        /* Switch off paging memory */
        mov     %cr0, %edx
        and     $0x7FFFFFFF, %edx
        mov     %edx, %cr0

        mov     $1024, %edx

        /* Copy page data */
loop:

        mov     (%ebx), %eax
        mov     %eax,   (%ecx)
        add     $4, %ebx
        add     $4, %ecx
        dec     %edx
        jnz     loop

        /* Switch on paging memory */
        mov     %cr0, %edx
        or      $0x80000000, %edx
        mov     %edx, %cr0

        /* Pop EFLAGS and EBX */
        popf
        pop     %ebx

        ret


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

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Ужас... Саму clone_directory покажи.


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

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


Код:
/*------------------------------------------------------------------------------
//   Clone pages directories
//----------------------------------------------------------------------------*/
page_directory_t* clone_directory(page_directory_t* src)
{
    u32int phys; /* Physical address of new directory */
    u32int offset = 0;
    int i = 0;
   
    /* Ctreate new directory */
    page_directory_t* dir = (page_directory_t*) kmalloc_ap(sizeof(page_directory_t), &phys);
   
    /* Clear directory */
    memset(dir, 0, sizeof(page_directory_t));
   
    /* Calculate physical address of page tables */
    offset = (u32int) dir->tables_phys_addr - (u32int) dir;
    dir->phys_addr = phys + offset;

    /* Clone page tables */
    for (i = 0; i < 1024; i++)
    {
        /* If table is not created */
        if (!src->tables[i])
            continue;
       
        /* Check cloned directory is kernel directory */
        if ( kernel_dir->tables[i] == src->tables[i] )
        {
            /* Make link to this table */
            dir->tables[i] = src->tables[i];
            dir->tables_phys_addr[i] = src->tables_phys_addr[i];
        }
        else
        {
            /* Copy table */
            u32int phys = 0;
           
            dir->tables[i] = clone_table(src->tables[i], &phys);
            dir->tables_phys_addr[i] = phys | 0x07;
        }       
    }
   
    return dir;
}


Код:
/*------------------------------------------------------------------------------
//   Clone table
//----------------------------------------------------------------------------*/
page_table_t* clone_table(page_table_t* src, u32int* phys_addr)
{
    page_table_t* table = 0;
    int i = 0;
   
    /* Create new table */
    table = (page_table_t*) kmalloc_ap(sizeof(page_table_t), phys_addr);   
    /* Clear table */
    memset(table, 0, sizeof(page_table_t));
   
    /* for each page in table */
    for (i = 0; i < 1024; i++)
    {
        /* if page has not frame */
        if (!src->pages[i].frame)
            continue;
       
        /* Allocate new frame */
        alloc_frame(&table->pages[i], 0, 0);
       
        /* Clone all flags */
        if (src->pages[i].present)
            table->pages[i].present = 1;
       
        if (src->pages[i].rw)
            table->pages[i].rw = 1;
       
        if (src->pages[i].user)
            table->pages[i].user = 1;
       
        if (src->pages[i].access)
            table->pages[i].access = 1;
       
        if (src->pages[i].dirty)
            table->pages[i].dirty = 1;
       
        copy_page_physical(src->pages[i].frame*PAGE_SIZE,
                           table->pages[i].frame*PAGE_SIZE);
    }
   
    return table;
}


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

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
Это полный абзац... Нужно ввести статью за издевательство над железом и за посягательство на право называться системным программистом.

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


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

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

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

Вот ссылка на оригинал


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

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


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

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


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

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