Hlavní navigace

Co před námi tají /proc (7)

Tomáš Kašpárek

Pokud šlo vše dobře, je toto je první díl, který k vám přišel dříve jak po týdnu. Jen doufám, že mi to pracovní nadšení vydrží dost dlouho. Dnes se podíváme na několik informací o samotném jádře.

Opět dle tradice výpis základního adresáře /proc. Tečka před názvem znamená, že jsme daný soubor/adresář již probrali:

  .840     .devices      kcore    modules     stat     ide/
  .842     .dma          kmsg     mounts      swaps    irq/
  .847     .execdomains  ksyms    mtrr        uptime   net/
  .848     .filesystems  loadavg  partitions  version  nv/
  .apm     .interrupts   locks    pci         bus/     sys/
  .cmdline .iomem        meminfo  self@       driver/  sysvipc/
  .cpuinfo .ioports      misc     slabinfo    fs/      tty/

Dnes poprvé narazíme na informace, které jsou z bezpečnostního hlediska problematické, a proto jsou jako jedny z mála v systému proc pouze pro čtení a pouze pro superuživatele root. Na tomto serveru ovšem samozřejmě oprávnění ke čtení máme, a tak si můžou počíst všeci kořeni :).

kcore

V tomto souboru jádro zpřístupňuje celou fyzickou paměť přesně tak, jak ji jádro vidí. Hodí se tedy ideálně k odposlechu uživatelů (ideálně :) a případně (hlavně) k ladění nebo zjišťování detailních informací. Výpis je ve formátu ELF a informace jsou podobné klasickému výpisu core. To je však jen hlavička, po ní následují kopie jednotlivých stránek virtuální paměti z jádra. Detailní popis (v jazyce C :) najdete v souboru …/fs/proc/kco­re.c.

Ještě si neodpustím několik detailnějších informací, pokud po nich netoužíte, prostě následující dva odstavce přeskočte. Jde o to, jak vlastně vypadá rozložení fyzické paměti (fyz. adr. prostor = FAP) a jak vypadá logický adresový prostor (= LAP). Nejprve fyzická paměť. Když se startuje OS (Unixového typu – Linux), předá zavaděč operačního systému (LILO apod.) řízení na startovací kód obrazu jádra. Tento kód se skrývá v bootsektoru diskového oddílu, ze kterého se jádro startuje (to řeší zavaděč – LILO). Program v bootsektoru (stejně jako LILO pracuje – na x86 – v reálném režimu procesoru) provede nahrání obrazu jádra z disku do paměti, což je doprovázeno jistě známou hláškou „Loading …“. V paměti je obraz umisťován na začátek fyzické paměti. Na architektuře Intel x86 je to od jednoho megabajtu (z historických důvodů – viz MS DOS – kompatibilita se staršími jedinci řady x86), na jiných možná rovnou od nuly (to nemám možnost vyzkoušet). Dnes už není obraz jádra pouze kopírován z disku do paměti, nýbrž se provádí jeho rozbalení (dekomprimace) z formátu zip nebo bzip2. To proto, aby se obraz vešel na disketu a podobná zařízení s malou kapacitou. Takto je zaplácáno určité množství fyzické paměti a jede se dál. Konkrétně je paměť zaplácána vlastním kódem jádra (identifikovaným u programů poněkud matoucím označením text) a statickými (staticky alokovanými) inicializovanými daty (kupodivu označovanými jako data). Zbytek paměti je potom rozdělen na rámce po 4KB (na Intelu a na Aplha procesoru je to 8KB, jinde zase jinak) a jádro začne jako jeden z prvních úkolů připravovat struktury pro popis mapování virtuální paměti. Jakmile je to hotovo, je možno se přepnout do kýženého chráněného režimu a pokračovat v další inicializaci.

A teď co logický AP. Ten je u procesu tvořen logickými adresami v rozsahu 0 – 4GB. Z toho část pod hodnotou definovanou v jádře jako PAGE_OFFSET (implicitně 3 GB) je určena pro vlastní proces a do oblasti 3 – 4 GB se namapuje jádro. To potřebuje mít také svůj adresový prostor pro manipulaci s pamětí, nicméně ani jádro nemůže pracovat přímo s fyzickými stránkami paměti. Proto je část stránek obsazených jádrem a jeho daty na začátku paměti namapována na virtuální paměť ve zmiňovaném rozsahu (nad 3GB). Mapování je uděláno jednoduše tak, že když k fyzické adrese přidáte konstanty PAGE_OFFSET, dostanete virtuální adresu naopak. To samozřejmě platí jen v režimu jádra. Tak je v rozsahu PAGE_OFFSET až PAGE_OFFSET+ve­likost_RAM namapována skutečná fyzická paměť, což jádro využívá například k nulování nebo kopírování celých stránek. Potom následuje z bezpečnostních důvodů mezera v LAP jádra (aktuálně 8 MB) a začíná část adresového prostoru pro dynamickou alokaci paměti v jádře. Pokud si tedy v ovladači zařízení alokujete svých 12 kilobajtů paměti, dostanete virtuální adresu někde v tomto intervalu. Tato virtuální adresa bude ukazovat na stránku ve fyzické paměti, na kterou už ukazuje virtuální adresa z prvního mapování jádrem (v rozsahu PAGE_OFFSET až PAGE_OFFSET + velikost_RAM). V určitých případech by na ni mohlo ukazovat ještě i několik virtuálních adres jednotlivých procesů. Na konci virtuálního adresového prostoru jádra se nachází oblast vyhrazená pro tzv. „compile-time virtual memory“ (soubor …/include/asm-xxx/pixmap.h). Ty jsou určeny pro speciální případy, kdy je potřeba mít v čase kompilace části jádra pevně danou hodnotu adresy, ale její skutečné umístění je možné určit až při startování jádra. Při použití tohoto řešení je virtuální adresa konstantní a mění se fyzická adresa, na kterou se ta virtuální transformuje.

ELF hlavička tohoto souboru obsahuje také několik užitečných informací, nicméně její hlavní účel je pravděpodobně takový, aby výpis měl podobu běžného souboru core a mohl být tedy použit pro alespoň částečné ladění prostředky, jako je GDB apod. Pro zjištění obsahu vlastních informací v hlavičce doporučuji opět soubor kcore.c a hlavně funkci elf_kcore_sto­re_hdr.

Ukázkový výpis se tentokrát nekoná, asi si dokážete představit binární smetí. Na druhou stranu, kdybych se trošku snažil, můžu vám ukázat obsah stránky paměti, kde je uložen text tohoto článku. Alespoň byste viděli, jak Emacs uchovává v paměti své buffery.

kmsg

Ukázkový výpis byl vyroben příkazem cat /proc/kmsg > /tmp/kmsg, následným připojováním a odpojováním svazku s FAT32 filesystémem a poté vkládáním a rušením modulu apm.o. Veškeré akce musel provádět superuživatel, stejně tak výpis samotného souboru.

<4>MSDOS FS: Using codepage 852
<4>MSDOS FS: IO charset iso8859-2
<6>apm: BIOS version 1.2 Flags 0x17 (Driver version 1.14)

Tento soubor obsahuje zprávy vypisované jádrem, které se také objeví v syslogu. Opět se jedná o soubor, který může číst pouze superuživatel. Pokud se odsud přečtou nějaké informace, dle dokumentace k syslog (2) už nejsou zapsány do syslogu – lze je číst pouze jednou, ale v praxi se při čtení pouze zkopírují a objeví se následně i v syslogu. Veškeré logovací informace jsou ale bufferované, a proto dochází k určitým zpožděním.

K výpisu těchto informací lze stejně tak použít program dmesg, nebo přímo syslog a jeho soubory ve /var/log/. Syslog má tu výhodu, že přidá ještě další informace, jako čas pořízení výpisu a název počítače (to se hodí pro vzdálené provádění logování). Navíc se v souboru /proc/kmsg nezobrazují všechny hlášky, ale pouze ty, které jdou na konzoli. Nicméně úpravám a lidové tvořivosti se meze nekladou – vše podle hesla: „Co si pokazíš, to máš!“ :)

Našli jste v článku chybu?