Dentro il Sistema

OS2LDR e OS2KRNL - La segreta stretta di mano

Claudio Umana
 

Versione originale in Inglese di David C. Zimmerli
apparso su  Edm2 
tradotto liberamente da Claudio Umana

Introduzione

Nel mio articolo "All'interno del Kernel di Os/2" ho introdotto faticosamente i passi dell'inizializzazione dei moduli dell'OS2LDR come rivelato dal terminale di debug durante il boot-up del sistema. In questo articolo voglio far vedere in maniera più strutturale l'OS2LDR, focalizzandomi specialmente sull'interfaccia tra l'OS2LDR e l'OS2KRNL. Che io sappia, questa interfaccia, incluso circa 50 funzioni "Dos Helper", non è mai stata documentata né menzionata in qualsiasi materiale pubblico.


I L'indovinello

Per ricapitolare brevemente i miei precedenti studi: al sistema di inizializzazione di OS/2, il modulo OS2LDR, eseguito in modo reale, setta i chip PIC e il timer PIT, chiede al BIOS i dati della configurazione hardware, legge varie informazioni dal CMOS e dalla ROM, e infine carica (per esempio legge e applica il fixup) l'OS2KRNL e trasferisce il controllo al suo indirizzo di start, il sysInitializeOS2.


Questa conoscenza risolve il problema dell'interpretazione di tutti gli "incantesimi magici" che confluiscono attraverso il terminale di debug durante la fase di start-up, ma solleva anche una importante questione concettuale: perché il loader fa tutto questo? Il loader non dovrebbe solamente caricare il kernel, prenderne il controllo, e proseguire? Perché non lasciare che il kernel manipoli la comunicazione con il BIOS, inizializzando i chip delle periferiche, e interagendo con le porte del sistema per produrre una soddisfacente, pulita "risposta" del sistema operativo?


Le cose si complicano quando noi scopriamo che, dopo l'inizializzazione, lo "strato più basso" del codice di manipolazione degli interrupt del modo protetto - le istruzioni alle quali l'IDT punta direttamente - consiste di codice derivato dall'OS2LDR! Come è possibile che questo pezzo di modulo del loader del kernel sopravviva nel sistema completamente inizializzato, ben dopo che dovrebbe essere necessario? E che cosa mai ha a che fare il manipolatore di interrupt del modo protetto con il caricamento del kernel in modo reale?


II OS2LDR: molto più che un Kernel Loader

Risulta che OS2LDR è molto più che un loader per l'OS2KRNL. Esso incorpora anche una libreria di circa 50 funzioni call-back, conosciute internamente come funzioni "Dos Helper", che il kernel usa sia prima che dopo l'inizializzazione per dialogare con l'hardware del PC. Sembra che questa libreria sia l'inizio di un tentativo di isolare il nucleo delle funzioni del kernel - gestione dei task, gestione della memoria, manipolazione dei semafori, e così via - dal "nudo metallo" dell'architettura del PC - la conoscenza di che porte controllino quali chip di periferiche, come l'area dati del BIOS, e similari. Per quelli tra voi che hanno letto il libro su OS/2 per PowerPC, questi concetti dovrebbero cominciare ad essere famigliari. Potremmo parlare di "micro-kernel"?


In quello che segue tenterò di documentare le funzioni "Dos Helper". Queste presubilmente prendono il loro nome dal fatto che esse aiutano l'implementazione del kernel per le chiamate alle Dos* API o il supporto al CP-DOS, come usava il kernel per essere chiamato. Esse sono intese solo per l'uso dall'OS2KRNL, e non devono essere confuse con le DevHelp, Virtual DevHelp o FSHelp APIs.


III I dettagli dell'interfaccia

Quando l'OS2LDR passa il controllo all'OS2KRNL, esso passa un puntatore (nel SS:BX) alla struttura che chiamerò muKServiceStruct. Il suo layout è il seguente:


Offset Description


0 16:16 pointer to Arena Info Table

4 16:16 pointer to Boot Parameter Block

8 Physical boot drive # (80h = C, 81h = D, etc.)

9 Boot Mode Flags

0Ah 16:16 pointer to warm reboot entry point

0Eh 16:16 pointer to DosHelp function table

12h zero

14h devStrat entry point


L'area delle Info Table ha una lista di tutti gli oggetti in memoria che sono stati settati dall'OS2LDR, includendo anche tutti i segmenti del kernel, il mini-FSD (per esempio l'OS2BOOT), l'OS2DUMP, l'OS2LDR stesso, e gli spazi vuoti disponibili per le applicazioni e i device driver. Esso è un vettore di lunghezza 16h avente il seguente layout:


Offset Description


0 Starting physical address

4 Size

8 Starting virtual address

0Ch Selector

0Eh flags

10h object flags from the Object Table Entry in the load module

14h "System Object Id" as given in the Debugging Handbook, Vol. IV,

pp. 249 - 254


E la "tabella delle funzioni DosHelp" ha il seguente layout:


Offset Description


0 Interface version # --=0008 for OS/2 2.1, 0009 for Warp 3, etc.

2 16:16 pointer to DosHelp function #1

6 16:16 pointer to DosHelp function #2

... ... etc.


Le funzioni DosHelper possono essere separate in tre categorie: (1) quelle chiamate durante la fase del modo reale dell'inizializzazione del sistema, (2) quelle chiamate durante la fase del modo protetto del sistema di inizializzazione, e (3) quelle che possono essere chiamate in ogni momento dopo l'entrata nel modo protetto. Il primo gruppo sono indirizzati con il segmento del modo reale 9400 (per esempio: il valore esatto dipende dalla dimensione dell'OS2LDR e l'ammontare della memoria in modo reale installata); il secondo gruppo con il selettore di codice 0110h e il selettore di dati 0118h; il terzo gruppo con il selettore di codice 0100h e selettore di dati 0108h.


Per l'interfaccia per OS/2 2.1:


Function, Description

Category


1,1 get PIC masks and RTC/Config RAM data

2,3 reboot

3,3 enable NMI

4,1 get ax=low mem, bx=high mem

5,1 get hardware equip word (# of COM ports, # of drives,

# of parallel ports, math co-proc.)

6,2 set si,di to point to default BASEDEVs to be loaded

7,1 input dl; sets si to point to "diskette parameter info"

for drive dl

8 entry pt. to OS2DUMP

9 entry pt. to OS2DUMP

10,1 read sectors (for FAT boot)

11,3 debug comm routine

12,3 debug comm routine

13,3 debug comm routine

14,3 debug comm routine

15,3 sets PIT

16,3 turn on/off speaker

17,3 get PIC masks

18,3 set PIC masks

19,3 Real Time Clock access routine

20,3 Real Time Clock access routine

21,3 set video mode and initialize 8514 registers

22,3 stores SYSxxxx

23,1 writes SYSxxxx messages

24,2 set regs for system timer

25,3 set system timer (PIT #1, System Timer 0, counter 0)

26,3 enable watchdog timer

27,3 disable watchdog timer

28,2 set up IDT

29,2 mark end of loader stage 2

30,2 apply fixups to protected mode interrupt handling code

31,3 32-bit 8259 PIC setting routine

32,3 32-bit 8259 PIC setting routine - shut off IRQ (input AX=IRQ#)

33,3 32-bit system timer (PIT #1, system timer 0, counter 0) routine

34,3 32-bit system timer (PIT #1, system timer 0, counter 0) routine

35,2 sets delay count for function #38

36,3 clear math coprocessor busy flag

37,3 shut off IRQ 13 (math coprocessor IRQ)

38,3 delay or clear task-switch flag

39,3 get math coprocessor IRQ status

40,3 initialize math coprocessor

41,3 stub function -- just a retd

42,3 prepares 'OS2 !! SYSxxxx' string

43,3 speaker beep

44,2 sets ESI = &(list of system DLL names), ecx=length of list

45,3 speaker beep

46,3 call PS/2 model-specific function

47,3 check for RAM parity error

48,3 just sets carry and returns

49,3 PS/2 only

50,3 PS/2 only

51,3 PS/2 only

52,3 PS/2 only


L'interfaccia per OS/2 Warp 3 aggiunge 3 nuove funzioni, portando il totale a 55. In un futuro articolo spero di documentare queste nuove funzioni così come l'interfaccia di OS/2 Warp 4.


Naturalmente, tutti i soliti concetti vengono qui applicati circa l'uso delle interfacce non documentate. Comunque queste informazioni potrebbero essere utili come punto di partenza per qualcuno che desideri scrivere un loader personalizzato - o un kernel per questo compito.


Sono benvenuti eventuali commenti e problematiche per questo articolo: per favore all'indirizzo email davez@nni.com .


Copyright © 1999, David C. Zimmerli. All rights reserved.


[Pagina precedente] [Sommario] [Pagina successiva]