Що містить фізична адреса 0 у Linux x86?


12

Я не впевнений, чи має це питання перейти сюди або в reverseengineering.stackexchange.com

Цитування з вікіпедії :

У процесорі 8086 таблиця переривань називається IVT (таблиця векторів переривань). IVT завжди знаходиться в одному і тому ж місці в пам'яті, починаючи від 0x0000 до 0x03ff, і складається з 256 чотирьохбайтових реальних покажчиків дальнього режиму (256 × 4 = 1024 байти пам'яті).

Це те, що я знаходжу в моніторі qemu:

(qemu) xp/128xw 0
0000000000000000: 0xf000ff53 0xf000ff53 0xf000e2c3 0xf000ff53
0000000000000010: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000020: 0xf000fea5 0xf000e987 0xf000d62c 0xf000d62c
0000000000000030: 0xf000d62c 0xf000d62c 0xf000ef57 0xf000d62c
0000000000000040: 0xc0005526 0xf000f84d 0xf000f841 0xf000e3fe
0000000000000050: 0xf000e739 0xf000f859 0xf000e82e 0xf000efd2
0000000000000060: 0xf000d648 0xf000e6f2 0xf000fe6e 0xf000ff53
0000000000000070: 0xf000ff53 0xf000ff53 0xf0006aa4 0xc0008930
0000000000000080: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000090: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000c0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000d0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000e0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000100: 0xf000ec59 0xf000ff53 0xf000ff53 0xc0006730
0000000000000110: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000120: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000130: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000140: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000150: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000160: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000170: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000180: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000000190: 0x00000000 0x00000000 0x00000000 0xf000ff53
00000000000001a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001c0: 0xf000d611 0xf000ec4e 0xf000ec4e 0xf000ec4e
00000000000001d0: 0xf000d61a 0xf000d623 0xf000d608 0xf000ec4e
00000000000001e0: 0xf000ff53 0x00000000 0xf000ff53 0xf000ff53
00000000000001f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53

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

Відповіді:


9

Що б не залишилось у вашій прошивці.

У ідеальній сучасній системі процесор взагалі ніколи не переходить у реальний режим, як я пояснив у цьому запитанні SU & Q під назвою: У якому режимі працюють сучасні 64-бітні комп'ютерні чіп-комп'ютери Intel? , перший KiB фізичної пам’яті настільки ж не має значення, як Йохан Мірен висловився в іншій відповіді тут. Але багато сучасних прошивок (все-таки) мають підтримку сумісності , це означає

  • вони можуть перейти назад (так, назад , враховуючи, що вони перейшли безпосередньо з нереального режиму в захищений режим) з захищеного режиму в реальний режим, щоб запустити системні програмні засоби, записані в реальному режимі, наприклад, старі програми завантажувальних програм PC / AT MBR та VBR; і
  • вони надають старі інтерфейси програмного забезпечення в реальному режимі та встановлюють усі структури даних для цих API, на які покладаються вищезазначені програмні засоби системи.

Однією з таких структур даних є реальний режим IVT. Старі API прошивки в реальному режимі засновані на intінструкціях, а реальний режим IVT заповнюється вбудованим програмним забезпеченням як частина його ініціалізації з покажчиками на різні підпрограми обробки програмного забезпечення для цих інструкцій.

Програмне забезпечення системи захищеного режиму не потребує старих програмних програм API реального режиму і ніколи не запускає процесор у реальному режимі, тому реальний режим IVT в першій 1 Кбіт фізичної пам'яті не використовується. (Захищений режим v8086 не стосується фізичної адреси 00000000 і вище, пам’ятайте. Він адресує логічні адреси 00000000 і вище, що перекладаються таблицями сторінок.) У сучасних системах EFI прошивка передає операційній системі карту пам'яті фізичної пам'яті. завантажувальний інструмент, повідомляючи, які частини зарезервовані до вбудованого програмного забезпечення для власних цілей API захищеного режиму, а які частини операційна система може просто продовжувати і використовувати для свого пулу фізичної пам'яті. Теоретично перша сторінка фізичної пам'яті може бути в останній категорії.

На практиці, по-перше, прошивки часто позначають першу сторінку фізичної пам'яті як "код завантажувальних служб", це означає, що операційна система може вимагати її та просто продовжувати та використовувати її як частину свого пулу фізичної пам'яті, але лише після завантаження- Поточні послуги прошивки EFI були відключені операційною системою, а вбудоване програмне забезпечення зводилося лише до надання послуг, що працюють під час роботи. Приклад цього можна побачити в журналі ядра Linux (з add_efi_memmapопцією), показаному Finnbarr P. Murphy:

[0,000000] efi: mem00: type = 3, attr = 0xf, range = [0x0000000000000000-0x0000000000001000) (0MB)
який xe розшифровує з іншою програмою у більш читаному для людини вигляді:

[# 00] Тип: EfiBootServicesCode Attr: 0xF
      Фіз .: 0000000000000000-0000000000001000
      Вір: 0000000000000000-0000000000001000

На практиці, по-друге, Linux явно ігнорує цей діапазон фізичної пам’яті, навіть якщо прошивка каже, що вона може йти вперед і використовувати її. Ви виявите, що як на EFI, так і на не-EFI прошивки однаково, як тільки Linux має фізичну карту пам'яті, вона виправляє її ( у функції, названійtrim_bios_range ), в результаті чого з'являються повідомлення журналу ядра, такі як:

[0,000000] e820: оновлення [mem 0x00000000-0x00000fff] usable ==> зарезервовано

Це не стільки для того, щоб впоратися з сучасними прошивками EFI, де реальний режим IVT не є частиною API прошивки, як це справляється зі старими прошивками PC98, де це частина API прошивки, але прошивки повідомляють про це (через той самий той самий API), що і фізична пам'ять, доступна для операційної системи.

Тому, хоча теоретично, діапазон фізичної пам'яті може містити довільний код або дані, залежно від моментних потреб розподільників пам’яті ядра та віртуальної пам’яті, що користується попитом; на практиці Linux просто залишає його недоторканим, оскільки прошивка спочатку налаштовувала його.

А у вашій системі прошивка заповнила його реальними записами IVT. Записи IVT в реальному режимі - це лише 16:16 дальних покажчиків, і якщо ви подивитеся на свою пам’ять за допомогою 2-байтового гексадуму, ви можете насправді це побачити досить чітко. Деякі приклади:

  • Більшість ваших записів IVT вказують на F000: FF53, адресу в області ПЗУ в реальному режимі. Це, мабуть, манекен звичайний, що робить не більше ніж iret.
  • Запис IVT 1E вказує на F000: 6AA4, таблицю в цій самій області ПЗУ.
  • Запис IVT 1F вказує на C000: 8930, таблицю в області вбудованого програмного забезпечення відеорома в реальному режимі.
  • Запис IVT 43 вказує на C000: 6730, іншу таблицю в області вбудованого ПЗ для відеороликів реального режиму.

Подальше читання


Ні, я маю на увазі те, що я написав. Посібник для розробників програмного забезпечення для архітектури Intel том 3 глави 20 § 2.
JdeBP

Ну, у вас зараз, бо це; як пояснюється перше речення цього розділу. З цього підозрюю, що невпізнання загальної абревіатури "v8086" є свого роду шибболетом. (-:
JdeBP

Потрібно навчитися читати атрибутивні іменники. Або ще навчитися жити без грибного супу.
JdeBP

7

Оригінальна архітектура процесорів 8086 (реалізована як Реальний режим у процесорах 80286+) не має значення для Linux, що працює в захищеному режимі. За фізичною адресою 0 немає таблиці векторів переривань, натомість використовується таблиця дескрипторів переривань, що містить дескриптори переривань. IDT може знаходитися в будь-якому місці пам'яті.

Ядро Linux отримує карту фізичної пам'яті з вбудованого програмного забезпечення (BIOS або EFI), яке вказує, які кадри сторінки фізичної пам'яті можуть бути використані, а які зарезервовані чи відсутні. Діапазон корисних кадрів сторінок не є суміжним, але, як правило, у ньому є величезні отвори. Традиційно ядро ​​x86 Linux пропустило початок фізичної пам'яті, навіть якщо воно позначене як придатне для використання. Таким чином, фізична адреса 0 не використовується ядром Linux.


Це має сенс. Будь-яка ідея, з чого складається вміст, що залишився на цій невикористаній сторінці?
родео

Googling для 53 ffвиявляє, що це, швидше за все, насправді векторна таблиця переривань реального режиму 8086, створена прошивкою або завантажувачем.
Йохан Мірен

4

Демпінгова пам'ять

Ось альтернативний спосіб скинути вміст пам’яті всередині системи, порівняно з цим:

$ head /dev/mem | hexdump -C
00000000  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
00000010  53 ff 00 f0 53 ff 00 f0  cc e9 00 f0 53 ff 00 f0  |S...S.......S...|
00000020  a5 fe 00 f0 87 e9 00 f0  53 ff 00 f0 46 e7 00 f0  |........S...F...|
00000030  46 e7 00 f0 46 e7 00 f0  57 ef 00 f0 53 ff 00 f0  |F...F...W...S...|
00000040  22 00 00 c0 4d f8 00 f0  41 f8 00 f0 fe e3 00 f0  |"...M...A.......|
00000050  39 e7 00 f0 59 f8 00 f0  2e e8 00 f0 d4 ef 00 f0  |9...Y...........|
00000060  a4 f0 00 f0 f2 e6 00 f0  6e fe 00 f0 53 ff 00 f0  |........n...S...|
00000070  ed ef 00 f0 53 ff 00 f0  c7 ef 00 f0 ed 57 00 c0  |....S........W..|
00000080  53 ff 00 f0 53 ff 00 f0  53 ff 00 f0 53 ff 00 f0  |S...S...S...S...|
...
...
000afea0  00 00 00 00 00 00 00 00  aa aa aa 00 aa aa aa 00  |................|
000afeb0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000b0000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
000c0000  55 aa 40 e9 62 0a 00 00  00 00 00 00 00 00 00 00  |U.@.b...........|
000c0010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 49 42  |..............IB|

Аналіз

Верхня частина вище 000c0000 може бути пов'язана з завантажувачем. Чому я б підозрював це? Код 55aah у розташуванні 000c0000зазвичай може бути позначкою в пам'яті для таких речей, як тригер для BIOS для запуску вторинного завантажувача.

Довідка: Підпис завантаження - BIOS

  ss №1

Однак, враховуючи, що цей 55aah зустрічається в діапазоні c0000h-effffh, швидше за все, ця частина є заголовком розширення PNP:

Довідка: Специфікація завантаження BIOS

3.3 Пристрої з заголовками розширення PnP

Усі IPL-пристрої з опціональними ПЗУ повинні містити дійсний заголовок ROM з опцією, який знаходиться між адресами системної пам'яті C0000h та EFFFFh на границі 2k і починається з 55AAh. Завантаженням пристрою можна керувати, лише якщо він має заголовок розширення PnP. Заголовок розширення, адреса якого знаходиться в стандартному варіанті заголовка ROM при зміщенні + 1Ah, містить важливу інформацію, яка використовується для налаштування пристрою. Він також містить покажчики для кодування в опції ROM (BCV або BEV) пристрою, яку BIOS закликатиме до завантаження з пристрою. Дивіться додаток А до структури заголовка розширення PnP. Існує два способи завантаження пристрою IPL із заголовком розширення PnP. Він повинен містити BCV або BEV.

53ff ...

Щодо даних 53ffh, які є на початку. Мені незрозуміло, що це насправді. Подальше дослідження це, ймовірно, щось, що ядро ​​Linux написало там після завантаження BIOS MBR BIOS, передане ядро ​​Linux для завантаження.

Зазвичай завантажувач завантажує ядро ​​в пам'ять, а потім переходить до ядра. Потім ядро ​​зможе відновити пам'ять, яку використовує завантажувач (тому що вона вже виконала свою роботу). Однак можна включити код ОС у завантажувальний сектор і зберегти його резидентом після запуску ОС

Покопившись далі, я зміг знайти цей параграф із дослідницької роботи під назвою: Введення зловмисного коду через / dev / mem :

1 Пристрій пам'яті

/ dev / mem - це інтерфейс драйвера до фізично адресованої пам'яті. Первісний намір і mem, і kmem був для надання допомоги у налагодженні ядра. Ми можемо використовувати пристрій як звичайний символьний пристрій, використовуючи lseek () для вибору зрушення адреси. Пристрій kmem подібний, але забезпечує зображення пам'яті ядра в контексті віртуальної адреси. Сервер Xorg використовує мем-пристрій для доступу до відео-пам’яті VESA, а також векторної таблиці переривань BIOS ROM (IVT), розташованої за фізичною адресою 0x00000000, для управління режимами відео в режимі VM86. DOSEMU також використовує це для доступу до BIOS IVT, щоб мати можливість переривати BIOS для різних завдань (читання дисків, друк на консолі тощо).

Список літератури

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.