OSDev

для всех
Текущее время: 21 дек 2024, 16:50

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




Начать новую тему Ответить на тему  [ Сообщений: 34 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
СообщениеДобавлено: 31 май 2019, 21:55 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Himik писал(а):
Да, можно пока сделать именно так, с помощью битовой карты. Как для физических, так и для виртуальных страниц. Битовая карта физических страниц должна размещаться в общей памяти, а карту виртуальной памяти нужно размещать в объекте каждой задачи. Каталог таблиц тоже должен размещаться в объекте задачи. Тоесть, надо начинать описывать структуру задачи.


А как быть с ядром, ему память должна выделяться как и процессам теми же функциями и для ядра должна тоже быть своя карта виртуальных страниц и каталог? Или ядро не пользуется услугами менеджера.


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

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1426
А это как сделать. В Винде, например, часть памяти ядра фиксированная и всегда находится в физическом ОЗУ, а другая часть является выгружаемой, и система по мере необходимости подгружает туда свои кишки. Но на деле это лишь усложняет ядро и вызывает тормоза. Максимум, что имеет реальный смысл на практике, -- это добавлять к адресному пространству ядра новые страницы памяти для расширения динамической памяти (кучи) ядра, ежели в этом возникнет необходимость.

И, кстати говоря, надо предпринимать меры, чтобы задачи не могли выжрать всю память ядра -- например, определив квоты для задач и отказываясь выделять (прямо или косвенно) дополнительную память, если квота исчерпана.


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

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
SII писал(а):
И, кстати говоря, надо предпринимать меры, чтобы задачи не могли выжрать всю память ядра -- например, определив квоты для задач и отказываясь выделять (прямо или косвенно) дополнительную память, если квота исчерпана.


А что имеется в виду под памятью ядра? Например в KolibriOS на сколько я понял пространство делится на две части, нижние 2ГБ отводятся под процессы а верхние 2ГБ под ядро. Выходит что процесс не может занять больше 2ГБ? Но и ядру 2ГБ как то много. И из них тоже можно выделить память процессу? Просто например установлена квота в 100МБ, это значит процесс не может занять в ОЗУ больше 100МБ или это максимум что можно выделить из верхних 2ГБ для процесса?

SII писал(а):
Максимум, что имеет реальный смысл на практике, -- это добавлять к адресному пространству ядра новые страницы памяти для расширения динамической памяти (кучи) ядра, ежели в этом возникнет необходимость.


Этим и занимается функция brk() в UNIX системах?

И еще больше практический вопрос.
Допустим я загружаю ядро по RM адресу 0х1000, перевожу компьютер в PM, перемещаю ядро по адресу 0x100000 затем я должен создать каталог таблиц, в котором описать адресное пространство ядра. При этом виртуальные адреса страниц должны начинаться со второго гигабайта 0x80000000 и расти в сторону 0xFFFFFFFF. А физические адреса проецироваться на физический адрес начала ядра, т.е. 0х100000. Нужно создать столько страниц чтобы покрыть весь размер ядра. Затем я включаю страничную адресацию и прыгаю на виртуальный адрес 0x80000000. А код перекопированной части ядра должен начинаться с директивы org 0x80000000. После чего, если мне понадобиться доп. память для ядра, я могу выделить ее расширив адресное пространство вызвав функцию brk(), менеджер найдет свободные страницы назначит им виртуальные адреса продолжения ядра и вернёт первый виртуальный адрес созданной страницы. При создании процессов менеджер будет создавать каждому процессу свой каталог таблиц и заполнять его таблицами и страницами в зависимости от размера программы. виртуальные адреса у каждого процесса должны начинаться с 0х00000000 и до 0x7FFFFFFF. Получается правда что процесс не может занять больше 2ГБ... А для выделения процессу доп. памяти будет так же вызываться brk() расширяющая его адресное пространство.
Всё ли я правильно представляю?


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

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1426
FreeProger писал(а):
А что имеется в виду под памятью ядра?


Память, используемая ядром формально для своих личных целей -- в отличие от памяти, выделяемой процессам явным образом.

Проблема в том, что на многие "чихи" задач пользовательского режима ядро должно выделять память для собственных структур данных. Скажем, задача запускает новый поток -- нужно создать блок управления потоком. Задача запрашивает операцию ввода-вывода -- нужно создать блок запроса ввода-вывода. Задача создаёт семафор, таймер, мьютекс и т.д. -- ядро должно создать соответствующую внутриядерную структуру. Соответственно, память ядра постоянно расходуется на нужды задач, и, если задачи не ограничивать, может получиться так, что некая задача выжрет таким путём всю память ядра и тем самым блокирует работы системы в целом.

Кроме того, не смешивайте виртуальную и реальную память. Вся память процессов, вообще говоря, является виртуальной, и в каждый момент времени в реальном ОЗУ может находиться лишь малая её часть. Однако память ядра в идеале должна всегда лежать в реальной памяти. Поэтому память каждого процесса может быть достаточно "резиновой" и в 32-разрядном режиме ограничивается, по сути, лишь разрядностью виртуального адреса, в то время как память ядра ограничивается и разрядностью адреса, и фактически доступным объёмом ОЗУ с учётом того, что часть ОЗУ отожрана BIOSом, а какая-то часть должна быть оставлена для пользователя, причём, если физической памяти для процессов не хватает, часть страниц можно выгрузить в файл подкачки, а вот если памяти не хватает ядру, всё намного хуже (в общем случае система зависнет или упадёт -- ну или прибьёт какую-нибудь задачу в надежде освободить достаточно своей памяти).

FreeProger писал(а):
Например в KolibriOS на сколько я понял пространство делится на две части, нижние 2ГБ отводятся под процессы а верхние 2ГБ под ядро. Выходит что процесс не может занять больше 2ГБ? Но и ядру 2ГБ как то много. И из них тоже можно выделить память процессу? Просто например установлена квота в 100МБ, это значит процесс не может занять в ОЗУ больше 100МБ или это максимум что можно выделить из верхних 2ГБ для процесса?


Ну, Винде 2 гига ядру скорей мало, чем много :) Но это уже к вопросу правильного проектирования и реализации системы.
Кстати говоря, это деление адресного пространства поровну Колибри, надо полагать, скоммуниздила из Винды; Винда это позаимствовала из VAX/VMS (главный архитектор Винды НТ был главным разработчиком означенной системы и, естественно, использовал свой предыдущий опыт), а вот в VAX/VMS такое деление диктовалось особенностями архитектуры железа. Т.е. если в VAX/VMS такое решение было вынужденным, то повторять его в Винде не требовалось, просто об этом не задумывались, когда её создавали (4 гига ОЗУ казалось фантастикой). Собственно, в более поздних версиях Винды (по крайней мере, начиная с XP) оно и не обязательно: 32-разрядную систему можно запустить в режиме, когда ядру останется 1 гиг, а процессам будет выделяться 3 гига.

FreeProger писал(а):
Этим и занимается функция brk() в UNIX системах?


Понятия не имею, Унихи никогда меня не интересовали (точней, интересовали, но ровно до того момента, когда я не понял, что они примитивнее даже более ранних систем).

FreeProger писал(а):
И еще больше практический вопрос...

Всё ли я правильно представляю?


Вроде бы да.

На самом деле, размещать ядро, начиная его непременно с 80000000, не требуется. Можно, например, запихнуть его в самые верхие адреса (близко к FFFFFFFF) и расширять (если будет такая нужда) вниз. А можно разместить ядро с нулевого виртуального адреса, а задачи пользователя -- с какого-то более высокого (на самом деле, в большинстве систем в своё время поступали именно так, нынешнее разделение, как я уже говорил, -- наследие VAX/VMS, где оно навязывалось железом). Наконец, виртуальное адресное пространство что ядра, что задач вовсе не обязано быть непрерывным.


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

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Большое спасибо за разъяснения, по не многу начинает проясняется что и как делать.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 01 июн 2019, 22:30 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
FreeProger писал(а):
А как быть с ядром, ему память должна выделяться как и процессам теми же функциями и для ядра должна тоже быть своя карта виртуальных страниц и каталог? Или ядро не пользуется услугами менеджера.
Да, только пользовательские процессы с 3 уровня доступа смогут их вызывать только через шлюзы. Обычно, используя команды int или syscall. При этом менеджер физической памяти им совсем не нужен, им нужна только виртуальная память, или просто brk().


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

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Цитата:
Да, только пользовательские процессы с 3 уровня доступа смогут их вызывать только через шлюзы. Обычно, используя команды int или syscall. При этом менеджер физической памяти им совсем не нужен, им нужна только виртуальная память, или просто brk().


Понял, спасибо.


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

Зарегистрирован: 10 май 2007, 11:33
Сообщения: 1206
FreeProger писал(а):
Допустим я загружаю ядро по RM адресу 0х1000, перевожу компьютер в PM, перемещаю ядро по адресу 0x100000 затем я должен создать каталог таблиц, в котором описать адресное пространство ядра. При этом виртуальные адреса страниц должны начинаться со второго гигабайта 0x80000000 и расти в сторону 0xFFFFFFFF. А физические адреса проецироваться на физический адрес начала ядра, т.е. 0х100000. Нужно создать столько страниц чтобы покрыть весь размер ядра.
Лучше выделять страницы расширенной памяти, не обращая внимание на их физ. адреса. Т.е. будет неплохо, если код ядра будет располагаться в последовательных физ. страницах, но он не обязательно должен располагаться по адресу 0х100000 (например, в начале могут располагаться страницы, необходимые для организации таблицы страниц). Если "нераспакованное" ядро первоначально загружается в базовую память, вы можете сначала включить пагинацию, выделить и отобразить память под ядро, а уже потом туда скопировать код и данные ядра (сам участок выделяемой памяти может быть больше, т.к. после инициализированных данных может быть секция неинициализированных данных, т.н. bss, которую можно не выравнивать на границу страницы).

Цитата:
Затем я включаю страничную адресацию и прыгаю на виртуальный адрес 0x80000000. А код перекопированной части ядра должен начинаться с директивы org 0x80000000. После чего, если мне понадобиться доп. память для ядра, я могу выделить ее расширив адресное пространство вызвав функцию brk(), менеджер найдет свободные страницы назначит им виртуальные адреса продолжения ядра и вернёт первый виртуальный адрес созданной страницы.
Для ядра под "вершину brk" память обычно сразу выделяется, а уже выше идет "четвертая" секция под большие таблицы ядра и т.п. Модули ядра могут располагаться либо до этой секции, также используя ее, либо после, имея собственную подобную секцию.

Цитата:
При создании процессов менеджер будет создавать каждому процессу свой каталог таблиц и заполнять его таблицами и страницами в зависимости от размера программы. виртуальные адреса у каждого процесса должны начинаться с 0х00000000 и до 0x7FFFFFFF. Получается правда что процесс не может занять больше 2ГБ... А для выделения процессу доп. памяти будет так же вызываться brk() расширяющая его адресное пространство.
Про 2 Гб и соответственно базу ядра 0x80000000 уже написали (у меня, например, это значение можно менять при компиляции ядра). Говорить, что brk расширяет адресное пространство, не совсем корректно (хотя иногда встречается такая терминология). Тут "вершина brk" действительно может спокойно меняться в пределах "четвертой" секции, расширяя bss. Но это вершина непрерывной памяти процесса (не обязательно целиком отображенной). А в конце "пользовательского" адресного пространства может, например, располагаться стек (стеки при использовании многопоточности).


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

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Кто может подсказать? Я всегда считал что первые 1024Кб
Отводятся под вектора прерываний реального режима, разве они не должны быть отображены в карте памяти получаемой от BIOS функцией E820 прерывание 15h. Я накидал макрос для получения карты памяти и решил посмотреть что в ней.
Код:
macro m_get_smap
{
  pushad
  push es
  push SMAP_SEG
  pop es
  mov di,SMAP_OFF ; ES:DI Указатель на буфер, отступим два байтам
  xor ebx,ebx       ; Значение возвращенное предыдущим вызовом
  @@:
    mov eax,0xE820     ; Номер функции
    mov ecx,24         ; Размер буфера для принятия ячейки из таблицы (как минимум 20 байт)
    mov edx,0x534D4150 ; Строка "SMAP"
 
    int 15h
   
    mov [SMAP_SIZE],bx ; Запишем колличество таблиц
   
    prints "EBX: "
    printh ebx, 4, 1

    prints "low_address: "
    mov eax, dword[es:di]
    printh eax
    prints " "
 
    prints " | height_address: "
    mov eax,dword[es:di+4]
    printh eax, 8, 1
 
    prints "low_size: "
    mov eax,dword[es:di+8]
    printh eax
    prints " "
 
    prints "| height_size: "
    mov eax,dword[es:di+12]
    printh eax, 8, 1
 
    prints "type: "
    mov eax,dword[es:di+16]
    printh eax, 2
    prints " "
   
    prints " | ACPI extended: "
    mov eax,dword[es:di+20]
    printh eax, 8, 1
   
    add edi,24 ; передвигаем адрес в бувере
    test ebx, ebx
   jnz @b

    pop es
    popad
}


Получил то что на скриншоте.
Получается что первыми идут 654 336 байт и они имеют тип 1 т.е. доступны как обычная память для перезаписи.


Вложения:
Screenshot_2019-06-04-19-02-04.png
Screenshot_2019-06-04-19-02-04.png [ 162.92 КБ | Просмотров: 8899 ]
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 04 июн 2019, 19:23 

Зарегистрирован: 22 май 2019, 12:08
Сообщения: 34
Это карта памяти эмулируемая qemu с 32Мб ОЗУ. Я так понимаю что основную память можно брать из четвёртой таблицы, размер описуемой ею области 32 374 784 байт


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

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


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

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


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

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