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

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

  1. baldr

    baldr New Member

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

    В общем, содержимое памяти по адресу Х — то, что было прочитано согласно соответствующему протоколу. Если чипсету сказано перенаправлять обращения к F0000…FFFFF в оперативку, чип BIOS можно аккуратно достать. Не факт, кстати, что по этим адресам всё ещё живёт распакованный BIOS. :derisive:
     
  2. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    baldr
    А он там уже и не живет. Он давно уже наверх переехал в адреса 4 Гб-размер биоса
    s3dworld
    ОЗУ это ОЗУ и оно занимается только временным хранением данных, а вот процессор обращается к этому ОЗУ используя изрядно нашинкованное адресное пространство. При чем в кривой интелловской архитектуре пространство устройств PCI не может располагаться выше 4 Гб, поэтому все регистры и память устройств PCI проецируются на адресное пространство ближе к концу (4 Гб). Устройства PCI могут занимать огромный кусок адресного пространства и для памяти его может не хватить (только видео память, при достаточном ее количестве вырезает 0,5 Гб). Если для отображения всей памяти на адресное пространство не хватает 4 Гб, то вот оставшаяся память проецируется за 4ый Гб.
    На счет этого бита можешь не заморачиваться особо. Если все лежит в плоском адресном пространстве, то и стек и данные могут просто где-то находиться в одном и том же сегменте данных и этот бит не понадобится. Но вот если пользоваться механизмом сегментации для распределения памяти, то это понадобится для как раз таки сегмента стека.
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Причём дотянуться до неё используя механизм сегментов нельзя - придётся включать страницы и подкачивать память из за границы 4Гб в доступное сегментам 4Гб адресное пространство (АП) и обратно, например, используя часть доступного АП как окно в эту "запредельную" память :)
     
  4. s3dworld

    s3dworld Сергей

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

    Я имею в виду, чтобы работать так же как и в реальном режиме, только с большим диапазоном адресов. Понятное дело что была бы однозадачность.
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    s3dworld
    я же уже посоветовал тебе унреал в #11 - вторая ссылка с примером это как раз оно и есть - реальный режим с 4Гб диапазоном адресов.
     
  6. SII

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

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

    s3dworld Сергей

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

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Как минимум нужно почитать любую книжку, а не флудить на форуме.
     
  9. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Я тут решил для себя сделать справочник. Вот начал со структуры селектора сегмента. Она загружается в один из шести сегментных регистров (в зависимости что за сегмент нам нужен, хотя для длинного режима какие-то сегментные регистры игнорируются). Так вот, сам по себе селектор сегмента состоит из 16 бит. Так мне и интересно, а для чего вообще нужно поле RPL (Requestor Privilege Level)? То есть я конечно знаю что это, но зачем он нужен у селектора сегмента, если уровень привилегии я устанавливаю у дескриптора?
     
  10. s3dworld

    s3dworld Сергей

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

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

    И если в длинном режиме нет сегментов, то как же там всё устроено? Как это через плоскую модель памяти осуществляется. Есть ли странички?
     
  11. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    s3dworld
    минимум для перехода в защищенный режим
    Код (Text):
    1. sub sp, 12
    2. mov bp, sp
    3. mov dword [bp+0], gdt_ptr
    4. mov word [bp+4], gdt_limit
    5. sgdt [bp+6]
    6. lgdt [bp+0]
    7. mov eax, cr0
    8. test al, 1
    9. jnz already_in_PM
    10. or al, 1
    11. mov cr0, eax
    12. jmp code_sel:code_ptr
    13.  
    14. ...
    15.  
    16. code_ptr:
    17. ;если нужно
    18. mov ds, data_sel
    19. mov es, data_sel
    20. mov fs, data_sel
    21. mov gs, data_sel
    22. mov ss, stack_sel
    23. ...
     
  12. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Вообще-то там есть и GDT и страничная адресация. Причём страничная адресация обязательная, в отличии от простого PM. Для перехода тебе потребуется GDT также на 3 элемента - NULL, код и данные + полноценный каталог страниц. Только не 2 уровневый, а 4-х. Единственное отличие от обычного PM - у сегментов игнорируется база и лимит. То есть все сегменты имеют базу 0 и лимит 2 ^ 64 байт. Однако такие же сегменты тебе никто не запрещает описать и в простом PM, а при условии, что ещё нужна таблица страниц long mode сложнее PM.
    Без ничего нет и PM. Нужна таблица дескрипторов сегментнов. Как минимум. Можно перейти в long mode минуя 32-битный режим - сделать - просто вместо jmp CODE32_SELECTOR:start32 сделать jmp CODE64_SELECTOR:start64.
    Если у тебя нет нужды в 64-битной арифметике,только 2 ГБ ОЗУ и не нужна многозадачность, то зачем тебе сейчас вообще страничная адресация? Сделай 4 ГБ сегменты и тебе будет доступна вся память. Вот тебе даже код:
    Код (Text):
    1.         lgdt [gdtr]
    2.         cli
    3.         mov eax, cr0
    4.         or eax, 1
    5.         mov cr0, eax
    6.         jmp 8:start32
    7. use32
    8. start32:
    9.        mov ax, 16
    10.        mov ds, ax
    11.        mov es, ax
    12.        mov fs, ax
    13.        mov gs, ax
    14.        mov ss, ax
    15.        mov esp, новый указатель стека, потому что старый теперь ведёт не туда куда надо, если SS в RM был не равен 0
    16.        ; Всё. Мы в PM. Нам доступны все 4 ГБ памяти. Достаточно просто написать mov dword[0x12345678], 0x87654321
    17. ...
    18. gdt dq 0,\
    19.     0x00CF9A000000FFFF,\ ; kernel 32-bit code
    20.         0x00CF92000000FFFF   ; kernel 32-bit data
    21. gdtr:
    22.         dw 8 * 3 - 1
    23.         dd gdt
    max7C4
    Вы меня опередили
    UPD:
    http://flatassembler.net/examples/longmode.zip - Тут минимум для перехода в long mode в одном файле, а в другом помимо перехода ещё и обработка прерываний.
     
  13. s3dworld

    s3dworld Сергей

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

    Страничную адресация мне действительно не нужна. Про то что нет сегментной адресации в длинном режиме - это я прочитал тут http://ru.osdev.wikia.com/wiki/Режим_IA-32e.

    Значит получается что она есть. Но меня всё же интересует именно длинный режим, так как я хочу производить операции над 64-битными числами.

    Я читал официальную документацию от AMD и там сказано что переключиться в длинный режим можно только из защищённого. Неужели в официальном мануале ошиблись?

    Мне вот стало не понятно следующее:

    Неужели это правда?
     
  14. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Ничего особенно плохого здесь нет. Просто при переключении задач ОС должна сама сохранить регистры ЦПУ. А вообще аппаратная многозадачность была сделана достаточно криво (не то что бы с багами, просто сам механизм кривой), что современные ОС ей не пользуются, потому что свою реализацию сделать проще, да и на переносимость ОС это влияет (на других архитектурах никогда не было аппаратной многозадачности).
    Нет. Там не ошиблись. В варианте предложенном мною мы делаем так:
    Код (Text):
    1. mov eax, cr0
    2. or eax, 0x80000001
    3. mov cr0, eax
    4. jmp CODE64_SELECTOR:start64
    5. use64
    6. start64:
    7. mov rax, 0x1234
    8. ...
    ПРоц переключается в PM ещё по команде mov cr0, eax (а ещё включается страничная адресация тут же, поэтому cr3 должен быть правильно настроен, long mode разрешён, а страничное расширение включено - словом, всё, что требуется для long mode). Просто мы прыгаем на 64-битный код из 16-битного, а не 32. Таким образом экономим на 32-битном сегменте. Кстати, сегмент данных в long mode потребуется только когда мы подумаем о разделении кода ядра и кода приложений. Пока всё выполняется на одном уровне привелегий и нет TSS нам достаточно двух селекторов в GDT - NULL и код. Значение DS, ES, FS и GS игнорируются. Должны быть корректно настроены только CS и SS. Причём SS только если происходит возврат по iretq или retf на другой уровень привелегий, а вам это сейчас не нужно.

    К слову для длинной арифметики long mode не нужен. Хватит SSE, которым кажется можно пользоваться даже в RM. Ну в обычном PM точно.
     
  15. s3dworld

    s3dworld Сергей

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

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Нет. В длинном режиме страничная адресация обязательна.
    Не совсем. В отличии от других режимов тут сегменты нужны только для определения прав доступа и разрядности кода. Остальные поля игнорируются (исключение - дескриптор TSS). То есть сегментации в привычном понимании нет.
    Посмотри пример с flatassembler.net. Там маппят первый мегабайт памяти. Всю память маппить не надо! Это займёт слишком много времени и памяти. Тем более в длинном режиме, когда значащая часть адреса - 48 бит. У тебя просто в память таблицы не поместятся. Тебе нужен простейший менеджер памяти, который выполнял бы три функции - получение N физических страниц, освобождение N физических страниц начиная с X, маппинг N физических страниц,начиная с X к виртуальному адресу Y каталога страниц B. Если хочешь - могу поделиться. Или определись, что тебе нужно (IO APIC, видюха, сколько-то МБ ОЗУ) и мапь при переходе в LM.
     
  17. s3dworld

    s3dworld Сергей

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

    Конечно хочу чтобы поделился, только для меня лучше больше не кодом, а алгоритмом))

    Значит суть такова: я заполняю глобальную таблицу дескрипторов где у меня будет первый элемент (с индексом 0) который трогать нельзя (просто он обязательно есть). Первый элемент (второй дескриптор) будет иметь базу 0 и лимит в 4^32 (этот один сегмент и будет представлять из себя плоскую модель памяти: код, данные и стек). Мне нужно будет самому определять диапазоны для каждой из программ (где ей можно данные хранить, где стек и прочее...).

    Потом я загружаю в регистр GDTR адрес где у меня моя таблица дескрипторов находится (кстати, это получается что в длинном режиме не используется регистр LDTR, то есть нет локальных таблиц дескрипторов, кажись).

    Я пока не прыгаю никуда (ни в 32-битный, ни в 64-битный код), так как в длинном режиме нужна страничная адресация, то мне нужно настроить регистр CR3. Как я понял, регистр CR3 указывает на начало каталога (таблицу) страниц. Только вот в статье http://www.wasm.ru/article.php?article=pipm07 так всё напутано, что я ничего не понял.

    Вот после того как я эти таблицы построю и загружу адрес этой таблицы в CR3, тогда мне можно прыгать в 64-битный код (правда есть же какие-то две таблицы страниц).

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

    Вообще, как я понял, лучше с самого начала всю доступную память поделить на странички (для меня лучше бы по 4 МБ), так ведь (чтобы в последствии не менять значения в каталоге страниц)?

    Интересно же, как же программе пользователя можно запретить в длинном режиме доступ к коду ядра или же к коду или данным другой программы?

    Для меня важно ещё бы научиться работать с точками останова и регистрами отладки (ведь без них далеко не уедешь начинающему). Вот тут вот http://ru.osdev.wikia.com/wiki/Кодирование_команд я увидел что существует 16 регистров отладки, но в документации AMD я насчитал только 8. Кто же врёт?
     
  18. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Есть! И сегменты остались только для этого. А в обычном PM Они ещё имели базу и лимит.
    Ещё как уедешь. На Bochs. Он предоставляет огромные отладочные возможности.
    Если у тебя ОС и программы на разных уровнях привелегий, то тебе надо 5 дескрипторов: NULL, код ядра, данные ядра, код приложения, данные приложения. При этом поля лимита и базы значения не имеют абсолютно - можешь писать туда что хочешь. Вот моя таблица дескрипторов:
    Код (Text):
    1. NULL_SELECTOR = 0
    2. KERNEL_CODE64_SELECTOR = 1 shl 3
    3. KERNEL_DATA64_SELECTOR = 2 shl 3
    4. USER_DATA64_SELECTOR = 3 shl 3
    5. USER_CODE64_SELECTOR = 4 shl 3
    6. USER_DATA32_SELECTOR = 5 shl 3
    7. USER_CODE32_SELECTOR = 6 shl 3
    8. TSS_SELECTOR = 7 shl 3
    9. align 16
    10. gdt dq 0,\
    11.     0x00A09A0000000000,\ ; kernel 64-bit code
    12.     0x00A0920000000000,\ ; kernel 64-bit data
    13.     0x00A0F20000000000,\ ; user 64-bit data
    14.     0x00A0FA0000000000,\ ; user 64-bit code
    15.     0x00CFF2000000FFFF,\ ; user 32-bit data
    16.     0x00CFFA000000FFFF,\ ; user 32-bit code
    17.     0x0000E90000003001 + ((tss and 0xFFFFFF) shl 16) + ((tss and 0xFF000000) shl 32),tss shr 32 ; TSS
    Пока ты не сделаешь TSS тебе последняя строчка не нужна. Если тебе не нужна поддержка 32-битных приложений, то убери и препоследнюю с предпредпоследней строчкой.
    LDT и раньше мало использовался, а сейчас в нём вообще необходимости нет, потому что все дескрипторы сегментов различаются лишь DPL (а TSS можно только в GDT делать).
    После mov cr0, eax таблицы страниц уже должны быть настроены, хотя код и 16-битный.

    Поскольку тебе для маппинга страниц потребуется доступ к произвольному физ. адресу опреативки, а примапить всю ты не можешь надо выделить некую временную страницу. Таблица страниц, которая на указывает на неё уже примаппена при старте. Вот для примера код для монтирования страниц:
    Код (Text):
    1. ; Временное монтирование страницы RAX
    2. temp_mount_page:
    3.     push rax
    4.     and rax, not 0xFFF
    5.     or rax, 111b
    6.     mov [temp_page_flags], rax
    7.     invlpg [temp_page]
    8.     pop rax
    9.     ret
    10. ; Монтирование RCX физических страниц начиная с RAX к виртуальному адресу RDX каталога страниц RBX
    11. map_virtual_pages:
    12.     push rax rcx rdx
    13. .map_page:
    14.     push rbx rcx rdx rax
    15.     mov rax, rbx
    16.     mov cl, 48
    17. @@:
    18.     call temp_mount_page
    19.     sub cl, 9
    20.     mov rdx, [rsp + 8]
    21.     shr rdx, cl
    22.     and rdx, 0x1FF
    23.     lea rdx, [qword temp_page + rdx * 8]
    24.     cmp cl, 12
    25.     jbe @f
    26.     mov rax, [rdx]
    27.     test rax, rax
    28.     jz .create_page_table
    29.     jmp @b
    30. .create_page_table:
    31.     push rcx [temp_page_flags]
    32.     mov rcx, 1
    33.     call alloc_phis_pages
    34.     pop [temp_page_flags]
    35.     invlpg [temp_page]
    36.     or rax, 111b
    37.     mov [rdx], rax
    38.     call temp_mount_page
    39.     push rax rdi
    40.     xor rax, rax
    41.     mov rdi, temp_page
    42.     mov rcx, 512
    43.     rep stosq
    44.     pop rdi rax rcx
    45.     jmp @b
    46. @@:
    47.     pop rax
    48.     mov [rdx], rax
    49.     pop rdx rcx rbx
    50.     invlpg [rdx]
    51.     add rax, 0x1000
    52.     add rdx, 0x1000
    53.     dec rcx
    54.     jnz .map_page
    55.     pop rdx rcx rax
    56.     ret
     
  19. s3dworld

    s3dworld Сергей

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

    Нашёл что shl это сдвиг битов влево на указанное количество. То есть если так:

    Код (Text):
    1. shl EAX,2
    То биты в регистре EAX сдвинутся влево (наверное два новых бита справа будут нулями). А вот такая вот конструкция:

    Мне не понятна. Что она значит?
     
  20. KIV

    KIV Member

    Публикаций:
    0
    Регистрация:
    16 июл 2009
    Сообщения:
    231
    Я константу объявляю. После этого KERNEL_CODE64_SELECTOR = 8
    А mov eax, KERNEL_CODE64_SELECTOR прокомпилируется в mov eax, 8