|
OS2LDR e OS2KRNL - La segreta stretta di manoClaudio 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. |