I když je většina kódu v linuxovém jádře napsána v C, stále existuje mnoho částí tohoto kódu, které jsou velmi specifické pro platformu, kde běží, a je třeba s tím počítat.
Jedním konkrétním příkladem je virtuální paměť, která funguje podobným způsobem na většině architektur (hierarchie tabulek stránek), ale má specifické podrobnosti pro každou architekturu (jako je počet úrovní v každé architektuře, a to se zvyšuje i na x86 s zavedení nových větších čipů.) Kód linuxového jádra zavádí makra pro zpracování těchto hierarchií, které může kompilátor obejít na architekturách, které mají méně úrovní tabulek stránek (takže kód je napsán v C, ale bere podrobnosti o architektuře do zvážení.)
Mnoho dalších oblastí je velmi specifických pro každou architekturu a je třeba je řešit pomocí kódu specifického pro oblouk. Většina z nich však zahrnuje kód v jazyce symbolických instrukcí. Příklady jsou:
-
Přepínání kontextu :Kontextové přepínání zahrnuje uložení hodnoty všech registrů pro vypínaný proces a obnovu registrů z uložené sady procesu naplánovaného do CPU. Dokonce i počet a sada registrů je velmi specifická pro každou architekturu. Tento kód je obvykle implementován v assembleru, aby umožnil plný přístup k registrům a také aby se ujistil, že běží co nejrychleji, protože výkon přepínání kontextu může být pro systém kritický.
-
Systémová volání :Mechanismus, kterým může kód uživatelského prostoru spustit systémové volání, je obvykle specifický pro architekturu (a někdy dokonce i pro konkrétní model CPU, například Intel a AMD pro to zavedly různé instrukce, starší CPU mohou tyto instrukce postrádat, takže podrobnosti pro ty bude stále jedinečný.)
-
Obsluhy přerušení :Podrobnosti o tom, jak zacházet s přerušeními (hardwarovými přerušeními), jsou obvykle specifické pro platformu a obvykle vyžadují určité lepidlo na úrovni sestavení, aby bylo možné zvládnout specifické konvence volání používané pro platformu. Také primitiva pro aktivaci/deaktivaci přerušení jsou obvykle specifická pro platformu a vyžadují také assembler.
-
Inicializace :Podrobnosti o tom, jak by měla probíhat inicializace, také obvykle zahrnují podrobnosti, které jsou specifické pro platformu a často vyžadují nějaký kód sestavení pro zpracování vstupního bodu do jádra. Na platformách, které mají více CPU (SMP), jsou podrobnosti o tom, jak převést další CPU online, obvykle také specifické pro platformu.
-
Uzamykání primitiv :Implementace zamykacích primitiv (jako jsou spinlocky) obvykle zahrnuje také detaily specifické pro platformu, protože některé architektury poskytují (nebo preferují) různé instrukce CPU, aby je mohly efektivně implementovat. Některé budou implementovat atomické operace, některé poskytnou cmpxchg, který může atomicky testovat/aktualizovat (ale selže, pokud se jiný zapisovač přihlásí jako první), jiné budou obsahovat modifikátor "lock" pro instrukce CPU. Ty budou často zahrnovat také psaní kódu assembleru.
Pravděpodobně existují další oblasti, kde je v jádře (nebo konkrétně v jádře Linuxu) potřeba kód specifický pro platformu nebo architekturu. Podíváme-li se na zdrojový strom jádra, pod 02
a pod 12
kde najdete další příklady.
Některé jsou skutečně překvapivé, například uvidíte, že počet systémových volání dostupných na každé architektuře je odlišný a některá systémová volání budou v některých architekturách existovat a v jiných ne. (I na x86 se seznam systémových volání mezi 32bitovým a 64bitovým jádrem liší.)
Stručně řečeno, existuje spousta případů, které si jádro musí uvědomit a které jsou specifické pro platformu. Linuxové jádro se snaží většinu z nich abstrahovat, takže algoritmy vyšší úrovně (například jak funguje správa paměti a plánování) mohou být implementovány v C a fungují stejně (nebo většinou stejně) na všech architekturách.
Kromě portování linuxového jádra budete muset definovat binární rozhraní aplikace (ABI) pro programy "uživatelského prostoru" a portují nejnižší vrstvy zásobníku softwaru uživatelského prostoru. Linux se obvykle používá s nízkoúrovňovými komponentami uživatelského prostoru z projektu GNU, z nichž nejkritičtější jsou:
- Kompilátor C, assembler a linker:GCC a GNU Binutils. Pro zcela novou architekturu CPU musíte tento software portovat ještě předtím, než vůbec začnete portovat jádro, protože jádro je samo C program a musí být zkompilováno. Pokud již existuje "back-end" podpora pro CPU vaší platformy, ale ne s Linuxem jako jádrem operačního systému, máte podstatně méně práce a možná budete schopni odložit většinu práce, dokud nebude jádro fungovat. běží.
- Běhová knihovna C:"GNU libc". Tato knihovna obsahuje kód, který vytváří systémová volání a jinak interaguje přímo s jádrem.
- Knihovna "rozhraní cizích funkcí", libffi, která je nezbytnou součástí mnoha překladačů jazyků na vysoké úrovni a provádí jeden z mála zbývajících úkolů, které vyžaduje malé množství ručně psaného jazyka symbolických instrukcí.
Mnoho dalších částí softwaru má volitelné komponenty závislé na platformě; například procházení webu bude podstatně rychlejší, pokud napíšete ručně optimalizovaná kryptografická primitiva pro NSS a OpenSSL pro vaši novou architekturu CPU a back-endy pro kompilaci just-in-time pro IonMonkey a V8. Ty však nejsou nezbytné pro vytvoření nové platformy.