Несколько вопросов начинающего

Тема в разделе "WASM.BEGINNERS", создана пользователем s3dworld, 6 окт 2010.

  1. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Всем доброго вечера!

    Про LDT и LDTR я, вроде бы, разобрался. Продолжаю дальше составлять свой справочник, вот добрался до регистра CR0. Вот формат регистра CR0:

    [​IMG]

    Я составил такое вот описание для полей MP, EM, TS, ET и NE:

    [​IMG]

    Но вот полный их смысл мне не понятен. Не могли бы уточнить и внести какие-то поправки в то, что я составил из нескольких литератур.

    Большое спасибо за внимание!
     
  2. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Читайте дальше, а не останавливайтесь после каждой непонятки. Как показывает практика, если не все вопросы, то 90% отпадут сами собой.
     
  3. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    SII
    +1. А еще лучше читать первоисточник или (что самое самое) официальные доки.
     
  4. Miyamoto

    Miyamoto New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2010
    Сообщения:
    46
    s3dworld
    Берите Intel Manuals уже и читайте :)

    И еще один совет: читайте внимательнее всю литературу, посвященную процам. Определений много, а еще когда в головах пейсателей (назовем так "переводчиков" интеловских манов) каша, то идут ошибки сплошняком.

    Вот и вы, предлагаете вычитывать ваш справочник, в то же время делая по 10 ошибок в простом посте:

    На счет локальной, не?

    Нет. Локальная таблица есть простой сегмент данных. А раз она сегмент -- то дескриптор, его описывающий, хранится в глобальной таблице.

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

    LDTR будет указывать на 1) видимая его часть - биты 0-15 - хранит в себе селектор (читай номер) дескриптора LDT, который хранится в GDT; 2) дескрипторный кеш - биты 16-79 - содержат дескриптор, описывающий LDT. Точнее поначалу не содержат, но как только подгрузите селектор в видимую часть -- невидимая обновится аппаратно так сказать.

    А вывод?
    -- да ни за что! Говоря проще, LDT просто адресуется через GDT. Но ни разу ни ее часть. Учите матчасть. (стих!)

    Обыкновенный сегментный дескриптор, описывающий LDT.

    Потому что художник бредил, видимо, когда интеловские маны переписывал/перерисовывал. Или наоброт, поумничать решил хехе.

    Сегментные дескрипторы по структуре своей одинаковы, будь то дескриптор из гдт или лдт.

    Будете забивать на eng и "учиться" по такой ерудне -- далеко пойдете, уверяю.

    См. выше.

    Все то же самое. Размеры/лимиты/гранулярности/полярности и т.п.

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

    Вообще да, тут и говорить особо не о чем при таких раскладах.

    baldr
    Мб вот так более верно ?

    Видимая часть LDTR содержит селектор дескриптора сегмента данных (дескриптора LDT то есть), который содержится в GDT. (?)
     
  5. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Читать официальные справочники от AMD и Intel это разумеется нужно. Но свой справочник я делаю по двум причинам:

    1. При написании текста справочника начинаешь вникать в суть дела (перепись с пониманием материала полезна).

    2. Я составляю справочник так, чтобы описываемый элемент помещался целиком на лист формата A4. Потом я это всё распечатаю и у меня будет перед глазами. Будет легче ориентироваться.
     
  6. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Не удастся сделать, чтоб всё влезало на одну страницу и даже лист (с двух сторон). Некоторые вещи слишком объёмные, чтобы их впихнуть на такую площадь. А насчёт п. 1 -- Вы, конечно, правы (именно поэтому изготовление _своих_ шпаргалок полезно -- в отличие от покупки уже готовых). Только вот составлять надо, используя мануалы, а не всякие книжки уважаемых авторов. Заодно и английский будет развиваться.
     
  7. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    SII
    Согласен с Вами полностью. Но я записываю то, что можно поместить: регистры и их описание, структуры и прочее.
     
  8. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    s3dworld
    то есть большую часть информации вы игнорируете?
     
  9. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Это про ссылки на Intel SDM/AMD APM? :derisive:
     
  10. Miyamoto

    Miyamoto New Member

    Публикаций:
    0
    Регистрация:
    23 окт 2010
    Сообщения:
    46
    s3dworld
    Да, но тогда надо все брать из нормальных источников и перепроверять еще в 10 местах и на разных языках.
    Вот тогда толк будет от всего.
    А если брать один кусок у кривого нетрезвого переводчика, кусок отсюда с васма хз от кого, кусок "сам додумаю" -- тогда есть риск "вникнуть" совсем в другое. А переучиваться труднее будет.

    А насчет того что информацию вы пропускаете -- имхо зря. На первых порах все должно быть как можно более избыточным, с водицей если хотите, чтобы все разжевывалось по три раза разными фразами и словами. От сжатости опять полезут непонятки.
     
  11. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Miyamoto,

    Практика — критерий истины. Лучший метод проверить догадку — накорябать тест и запустить его на реальном железе. Хотя адекватно оценить результаты теста — отдельная тема.
     
  12. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Всем доброго дня!

    Ну почему я пропускаю материал. Я вот читал книгу В.Л. Григорьева "Микропроцессор i486. Архитектура и программирование". Шёл от главы к главе. И то что там было пройдено, на то и составляю справочник, который распечатаю и который будет у меня всегда перед глазами (я люблю документы в текстовом виде, а не в электронном). Прочитал про сегменты и дескрипторы сегментов - составил про них в справочнике. Прочитал про страничную адресацию - составил про неё в справочнике. Теперь составляю про управляющие регистры (про CR0 и CR3 уже составил). CR2 можно вообще не составлять (там и так будет содержаться линейный адрес, при обращении к которому было вызвано исключение отсутствия странички). Далее составлю в справочнике описание про шлюзы вызова: исключений, ловушек и задач. А после про переключение задач (TSS). И вот так вот от шага к шагу - всё о чём узнаю, то опишу.

    На счёт страничной организации и виртуальной памяти. Я тут размышлял про это всё. Предположим у меня 32 МБ оперативной памяти (ОЗУ). Будем считать что у меня странички будут по 4 МБ. Даже предположим что у меня получится 8 страничных кадров:

    Вот как я это всё понимаю (адреса взял на бум):

    [​IMG]

    Предположим что для самой операционной системы понадобится 8 МБ, то есть 2 странички. А так как код ядра операционной системы не должен изменять адреса (находится в одном и том же месте), то для него я сразу определю страничные кадры: 0x01800000-0x01BFFFFF и 0x01C00000-0x01FFFFFF. А странички с индексами 1022 и 1023 всегда будут ссылаться на страничные кадры, которые содержат код операционной системы. Получается так:

    [​IMG]

    И вот пользователь решил запустить программу. Причём программа эта маленькая и не требуется для неё выделять много страниц (для всей программы хватит 3 страниц). Сначала ядро операционной системы выделяет 3 странички: код, данные стек. Странички эти будут содержать следующие индексы: 0, 1 и 2. В соответствующие страничные кадры записывается информация (коды, данные). Получается такая вот настройка:

    [​IMG]

    Все остальные странички (все кроме: 0, 1, 2, 1022 и 1023) содержат значение 0 в бите P (Present). Всё настроено и наконец-то передаётся управление по адресу 0x00000000 (то есть на страничку с индексом 0 и со смещением 0). Конечно в совершенстве передавать управление нужно будет с определённым смещением (мало ли где в коде находится стартовая точка), но это уже другая история. Программа работает в своё удовольствие пока вдруг не случится прерывание таймера. Такое прерывание нам говорит о том, что пришло время выполняться другой программе. Пускай следующая программа у нас такая же маленькая как и первая. И табличка уже будет выглядеть так:

    [​IMG]

    Все остальные странички (все кроме: 0, 1, 2, 1022 и 1023) содержат значение 0 в бите P (Present). В общем всё тоже самое и снова управление передаётся по адресу 0x00000000. Блин, снова сработал таймер и на очереди очередная маленькая программа. Опа, а свободных страничных кадров у нас уже нет! Тогда придётся что-то выгрузить и скорее всего то, что в списке на управление процессорным временем будет в самом конце. И если вычислить, то это будет только что выполняемая программа (предположим что у нас нет приоритетов). Тогда делаем ядро операционной системы делает следующее:

    [​IMG]

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

    [​IMG]

    Все остальные странички (все кроме: 0, 1, 2, 1022 и 1023) содержат значение 0 в бите P (Present). И снова передаём управление в 0x00000000. Предположим что снова сработал таймер и на очереди такая программа, что занимает 8 страничек (3 кода, 2 данных, 2 стека). Всё это можно реализовать множеством способом. Например у меня в голове такой...

    Код, данные и стек - это 3 странички. То есть если у нас нет 3 свободных страничных кадров (ну ведь глупо же для кода, данных и стека через одни страничный кадр всё делать - скорость упадёт), то мы их освобождаем. В данном случае мы их будем освобождать:

    [​IMG]

    И теперь на основании всех страничек, которые нужны программе, мы рассчитываем как построить таблицу страниц. Уж алгоритм я тут писать не стал, но конечный вариант такой:

    [​IMG]

    Все остальные странички (все кроме: 0, 1, 2, 1022 и 1023) содержат значение 0 в бите P (Present). И снова передаём управление на 0x00000000. И вот вдруг программе нужны данные из второй странички данных (разумеется она ничего про странички не знает, уж так вышло что обратилась ко второй страничке). У нас вызывается исключение отсутствия странички. И тут мы можем сделать разными путями (заменить страничный кадр данных на вторую страницу данных, взять страничный кадр предыдущей программы и туда вставить вторую страничку с данными, стек лучше не менять - я так думаю). Какой вариант лучше, я не думал. Хочу от Вас послушать какой вариант лучше выбирать. Я же пока сделаю так:

    [​IMG]

    И следом вот так:

    [​IMG]

    В общем сигать, прыгать и изгаляться как хотите можно - но лишь бы дать программе нормально работать. Больше свободных страничных кадров - больше сразу можно загрузить страничек. Собственно хранить информацию о выгруженных на жёсткий диск страничках - я пока понятия не имею. Наверное такую информацию можно где-то хранить (уж хотя бы индекс записать из таблицы) в структуре TSS. Возможно в стеке программы. В общем я не знаю. Хотелось бы услышать Ваше мнение.

    Ну и собственно сам вариант менеджера памяти у меня дурацкий или вполне нормальный?

    И ещё хотел спросить: мне сказали что в длинном режиме (L-Mode) работы процессора используется не 64-битная адресация, а 48-битная адресация (младшие 48 битов из 64-битного адреса). В связи с этим у меня несколько вопросов:

    1. Старшие 16 бит обязаны быть нулями, единичками или они игнорируются (могут содержать любое значение)?

    2. Можно ли переключением какого-нибудь бита в каком-нибудь регистре (я просто не знаю можно ли и где) вместо 48-битной адресации задействовать 64-битную?

    Большое спасибо за внимание!
     
  13. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Либо сказал какой-то дурак, либо Вы недопоняли. Адресация в любом случае 64-разрядная, просто старшие биты физически не реализованы (сэкономили транзисторы -- всё равно такой объём памяти в обозримом будущем не светит). Насчёт их значений в виртуальных адресах читайте мануалы про каноническую форму адреса.
     
  14. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    s3dworld
    один момент вы упустили. стек растет вниз и если под стек используется больше одной страницы, то первой подготавливать надо последнюю. т.е. ту, что с индексом 6.
    Вообще
    и если
    то абсолютно без разницы что заменять. Главное чтобы это в данный момент не нужно было текущей задаче (программе)
    обязаны быть
    прочитайте про cpuid а особенно про функцию 0х80000008
     
  15. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    max7C4
    Точно! Спасибо, про стек совсем не подумал. А обязаны быть чем: 0 или 1?
     
  16. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    А как лучше хранить информацию о том, что я залил страничку на жёсткий диск? К примеру структура элемента таблицы страниц такая:

    [​IMG]

    И если у меня будет бит P (Present) установлен в 0, то мне доступны будут следующие биты:

    [​IMG]

    Только вот не пойму для чего я их мог бы использовать.

    Я вот не пойму следующего, мне может нужно ещё какую-нибудь системную таблицу придумать, которая хранила бы список запущенных программ и описывала бы размещение их страничек?
     
  17. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    а почему бы не записать в биты помеченные как u при p=0 смещение в файле подкачке (в секторах), а бит помеченный как r/w при p=1 для такой фишки использовать как присутствие в файле подкачки. т.е. получается

    страница присутствует в памяти
    страница присутствует в файле подкачки и находится по смещению Sector*512
    для 4 Кб страниц понадобится 8 секторов поэтому для каждой следующей страницы младшие 3 бита смещения в файле будут равны 0 и их можно использовать как флаги (гарантированно), для 2/4 Мб страниц таких битов будет больше, но на это лучше не опираться.
    страница отсутствует как в памяти, так и на диске
    Код (Text):
    1.                            PPUR
    2. aaaaaaaaaaaaaaaaaaaaUUU00DACW//1 - действительный описатель страницы
    3.                            DTSW
    4.  
    5. sssssssssssssssssssssssssssssu00 - описатель страницы на диске
    6.  
    7. uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu10 - страница отсунствует
    [add]
    алгоритм обработки отказа страницы тогда будет примерно такой
    Код (Text):
    1. page_fault_handler:
    2.   push ebx
    3.   push esi
    4.   push edi
    5.   push eax
    6.   mov ebx, cr3
    7.   mov esi, cr2
    8.   shr esi, 12
    9.   mov edi, esi
    10.   and esi, 0x000003FF
    11.   shr edi, 10
    12.   and edi, 0x000003FF
    13.   mov eax, [ebx+edi*4]
    14.   test eax, 1
    15.   jnz catalog_present
    16.   test eax, 2
    17.   jnz invalid_catalog
    18.   call load_page
    19. catalog_present:
    20.   mov ebx, eax
    21.   mov eax, [ebx+esi*4]
    22.   test eax, 1
    23.   jnz page_present
    24.   test eax, 2
    25.   jnz invalid_page
    26.   call load_page
    27. page_present:
    28.   pop eax
    29.   pop esi
    30.   pop edi
    31.   pop ebx
    32.   iretd
    33. invalid_page:
    34.   call raise_exception, EXCEPTION_INVALID_PAGE
    35.   pop eax
    36.   pop esi
    37.   pop edi
    38.   pop ebx
    39.   iretd
    40. invalid_catalog:
    41.   call raise_exception, EXCEPTION_INVALID_PAGE
    42.   pop eax
    43.   pop esi
    44.   pop edi
    45.   pop ebx
    46.   iretd
    47. load_page:
    48.   and eax, 0xFFFFFFF8
    49.   call read_page_file
    50.   retd
    это самый простой и самый примерный вариант действия в таком случае
     
  18. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    max7C4
    Спасибо! Правда до меня не совсем всё дошло, видимо нужно несколько раз перечитать или просто ещё не готов к такому.

    А что касается защищённого режима (P-Mode) работы процессора и страничек размером в 4 КБ, то получается следующее: 1024 записи в каждой таблице второго уровня. Каждая запись занимает 4 байта.

    Всего таких таблиц второго уровня будет 1024.

    Ещё 1024 элемента в таблице первого уровня. Каждый элемент занимает по 4 байта.

    И всего получается 4198400 байт.

    Это что же, среди кода ядра операционной системы мне придётся выделить размер в 4100 КБ (это более 4 МБ) лишь под описание табличек? И для каждой задачи (программы) его перестраивать? Ну понятное дело что в большинстве случаях задачи будут не все элементы таблицы использовать, но всё же - придётся после каждой задачи подчищать все ненужные элементы в текущей задаче в 0 для бита P (Present). Это ведь сколько процессорного времени потребуется. Как же тогда делают правильно?
     
  19. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    s3dworld
    зачем. если программе надо 64 Кб под стек, 1 Мб под данные и 64 Кб кода, то для это радости достаточно
    1 каталог размером 4 Кб, 1 таблица размером 4 Кб и 1.125 Мб под данные и код всего 1160 Кб
    выглядеть это будет примерно так
    Код (Text):
    1. catalog dd page_table0,1023 dup (2)
    2. table dd page_code0,...,page_code15,page_data0,...,page_data255,page_stack0,...,page_stack15,736 dup (2)
    3. page_code0:
    4. ...
    5. page_code15:
    6. ...
    7. page_data0:
    8. ...
    9. page_data255:
    10. ...
    11. page_stack0:
    12. ...
    13. page_stack15:
    14. ...
    где catalog,table,page_codeXX,page_dataXXX,page_stackXX - символические обозначения адресов соответствующих станиц.
     
  20. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Вообще-то достаточно внимательно почитать описание работы страничного механизма (как он обрабатывает записи таблиц первого уровня, как -- второго и т.д.) и форматы элементов этих таблиц, чтобы понять простую вещь: вовсе не требуется для каждой задачи создавать весь набор таблиц нижних уровней. А чтобы не тратить кучу времени при переключении задач, все необходимые таблицы для каждой задачи создаются при её запуске, а в дальнейшем в них лишь вносятся необходимые коррективы.

    Книги по принципам работы ОС читайте.