Program startowy
‘Kernel’ wymaga specjalnego programu startowego (‘boot loader’), który wykonuje programy inicjujące systemu i przygotowuje środowisko działania.
Program startowy wykonuje następujące czynności:
- ‣ Przełącza do trybu graficznego o maksymalnej dostępnej rozdzielczości i zachowuje jego dane oraz ustawia tryb pamięci wyświetlacza jako ‘write‐combining’.
- ‣ Wczytuje dane z tablic ACPI bez interpretowania zawartości DSDT i SSDT.
- ‣ Wyszukuje pierwszy dostępny plik “/boot/kernel” w systemie plików OUXFS i wczytuje go do pamięci, a następnie przelicza zdefiniowane w nim adresy (‘relocation’).
- ‣ Wyłącza PIC, włącza x2APIC. Wczytuje i zachowuje numery przekierowanych przerwań.
- ‣ Wylicza urządzenia magistral PCI oraz ustawia tryb pamięci urządzeń jako ‘non‐cacheable’.
- ‣ Wczytuje, sortuje i zachowuje tablicę znaczenia zakresów adresów (‘memory map’).
- ‣ Tworzy od dołu przestrzeni adresów wirtualnych pamięć dostępną dla ‘kernela’. Scala zakresy pamięci zarezerwowanej na dole lub na górze tego bloku i przenosi program startowy.
- ‣ Przygotowuje poniżej 1 MiB pamięć (o tym samym adresie rzeczywistym i wirtualnym) na program startowy pozostałych procesorów i je uruchamia.
- ‣ Inicjuje ‹menedżer pamięci› i wyświetla ekran startowy.
- ‣ Ustawia tryby pracy procesora, adres stosu procesora startowego i uruchamia ‘kernel’, przekazując mu zgromadzone dane.
Program główny ‘kernela’
Wykonuje następujące czynności:
- ‣ Kopiuje do własnych struktur dane przekazane przez program startowy.
- ‣ Inicjuje ‹menedżer logowania›.
- ‣ Ustawia struktury przerwań procesora. Oblicza częstotliwość zegara APIC na podstawie zegara RTC.
- ‣ Inicjuje ‹sterownik przepływu wykonania› i kontynuuje uruchamianie pozostałych procesorów.
- ‣ Zwalnia niepotrzebną już pamięć startową.
- ‣ Inicjuje ‹menedżer ACPI/AML› i wykonuje procedury konfiguracji urządzeń.
- ‣ Inicjuje ‹sterowniki› urządzeń magistral PCI.
- ‣ Uruchamia środowisko okienkowe, inicjuje ‹sterowniki› klawiatury i myszy.
Funkcjonalności
Przepływ wykonania
System wykonuje się na najwyższym poziomie uprzywilejowania procesora (“ring 0”). Procedury są eksportowane (“_export”), by były dostępne dla programów dołączanych do ‘kernela’, są prywatne w ‘kernelu’ (“_private”) lub wewnętrzne w ‹module› (“_internal”).
Programy w systemie wykonują się w następujących środowiskach:
- • przerwanie procesora
- • procedura obsługi GUI
- • ‹zadanie› synchroniczne
Na razie programy wykonują się tylko na startowym procesorze.
‹Znaczniki stanu›, ‹raporty›, ‹cyklery› i ‹impulsatory› mają taką samą funkcjonalność jak w OUX/C+. Ponadto są do dyspozycji ‹raporty czasowe›.
Wprowadzenie ‹raportów czasowych›
Oczekiwanie na przerwanie procesora
Procedura “E_flow_Q_interrupt_I_wait” umożliwia oczekiwanie bez blokowania ‹zadań› na przerwanie procesora wykonujące procedurę “E_flow_Q_interrupt_I_signal”.
Międzyprocesorowy ‘lock’ z kodem powrotu
Umożliwia synchronizację wykonywania nie zatrzymujących się bloków programu między procesorami.
Po wywołaniu procedury “E_flow_Z_lock_I_lock” program wpada w pętlę oczekiwania na wejście do bloku programu, który może być jednocześnie wykonywany tylko przez jeden procesor w systemie wieloprocesorowym. Gdy jako argument procedury “E_flow_Z_lock_I_unlock_and_return” zostanie podany kod oznaczający błąd, to jest on przekazywany wszystkim oczekującym procesorom, umożliwiając przerwanie oczekiwania i emisję ‹zdarzenia› na każdym z nich. Następnie to ‹zdarzenie› jest obsługiwane tylko na tym procesorze, który je wyemitował.
O asynchroniczności wywołań sprzętowych
Międzyprocesorowe ‘locki’ ‘read’/‘write’ z kodem powrotu
Rozszerzają zwykły ‘lock’ o logikę nieblokowania się wzajemnie procedur tylko czytających dane.
Wywołanie procedury “E_flow_Z_lock_rw_I_lock_write” pozwala wykonać program tylko w przypadku, gdy ani ‘write‐lock’, ani ‘read‐lock’ nie są zajęte, natomiast wywołanie procedury “E_flow_Z_lock_rw_I_lock_read” umożliwia wykonanie w przypadku, gdy ‘read‐lock’ jest zajęty.
Kontrola błędów
Komunikaty linii
Komunikaty linii wypisuje się makrem nowej linii “G(fmt,…)” albo makrem kontynuacji linii “G_(fmt,…)”. Jako pierwszy parametr makra podaje się formatujący ciąg tekstowy. Po nim ewentualnie następują kolejne parametry zakodowane (prefiksem “%”) do wypisania w tym ciągu.
Po prefiksie “%” umieszcza się ewentualnie rozmiar bitowy parametru, ale na pewno – typ/format wypisywania. Są następujące typy parametrów:
- • “s” oznaczający ciąg tekstowy przydzielony przez ‹menedżera pamięci›, który zostaje przejęty przez ‹menedżera logowania›
- • “t” oznaczający ciąg tekstowy, który musi zostać zduplikowany
- • “z” oznaczający statyczny ciąg tekstowy, który jest obecny zawsze w kodzie programu
- • “x” oznaczający liczbę wypisywaną w formacie szesnastkowym bez znaku
‹Zdarzenia›
‹Zdarzenia› są emitowane w przypadku błędu wykonania procedury — w postaci kodu błędu. Do emisji służą makra blokowe “K(statement)” i “Kp(statement)” (dla procedur zwracających adres: “KP(statement)” i “KPp(statement)”) oraz makra liniowe wewnątrz bloków wyjścia z procedury “K_(error,statement)” i “Kp_(error,statement)” (〃: “KP_(statement)” i “KPp_(statement)”), którymi otacza się wywoływaną procedurę. Kody błędów mają następujące znaczenia:
- • 0 w procedurach zwracających adres to niewykonanie procedury tylko z powodu braku pamięci; w pozostałych procedurach kod ten powinien być zamieniany na ~0
- • ~0 to niewykonanie procedury bez skutków ubocznych; w procedurach zwracających adres niewykonanie z powodu niemożliwości ustawienia danych wewnętrznych ‹realizatora›
- • ~1 〃 ze zgubieniem pamięci/obiektu
- • ~2 〃 i uszkodzenie kolekcji obiektów lub obiektu będącego w kolekcji
- • ~3 〃 i uszkodzenie danych w pamięci nieulotnej
- • ~4 〃 i późno wykryty błąd ‘kompilacji’
W przypadku, gdy wywołanie procedury wróci z kodem błędu, a jest w normalnym toku wykonywania procedury nadrzędnej, to tylko w przypadku błędu ~0 w zwykłych procedurach, a w przypadku błędu 0 w procedurach zwracających adres — jest wykonywany blok wyjścia z błędem. W przypadku pozostałych kodów błędów jest wykonywany natychmiastowy powrót z procedury i kod błędu przekazywany wyżej. W przypadku, gdy wywołanie procedury wróci z jakimkolwiek kodem błędu wewnątrz bloku wyjścia z procedury (albo z błędem, albo zwykłego), to jest wykonywany natychmiastowy powrót z procedury z podanym kodem błędu lub wyższym (w sensie wartości bez negacji), jeśli z takim wróciła procedura.
‹Zdarzenia› są obsługiwane przy użyciu makra “K_V(context_ip,error,statement)”.
‹Moduły›
Interpretator ACPI/AML
Zawiera kompletny ‘parser’ AML zgodny z ACPI 6.5, natomiast interpretator instrukcji przebiega przepływ wykonania i oblicza wartości arytmetyczne, ale nie uzyskuje dostępu do pamięci. Na razie został rozbudowany na tyle, na ile symulator maszyny wirtualnej pozwalał przetestować. Posiada potencjał tworzenia w przyszłości procedur ACPI w kodzie maszynowym; po dodaniu ‘asemblera’.
W przypadku błędu składni podczas interpretacji startowej wyskakuje do nadrzędnego obiektu i kontynuuje.
Kontrolki graficzne
Są zaimplementowane następujące kontrolki graficzne możliwe do wstawienia do dowolnego okna:
- • napis
- • przycisk
- • jednoliniowe pole edycji tekstu
Jeśli kontrolki są używane w danym oknie, to należy w procedurze tworzenia ‹modułu› po utworzeniu okna wykonać “E_controls_M” oraz dodać je odpowiednimi procedurami ‹modułu› “controls”.

