Newsgroup: it.comp.lang.c++
Titolo: Cosa succede all'avvio del PC?

Perdonatemi, so che questo non č il NG piů adatto per una simile
domanda, ma non ho trovato NG italiani che trattassero questi
argomenti.
La domanda č questa: qual'č la sequenza esatta di operazioni che il PC
svolge immediatamente dopo che č stato acceso? Se non sbaglio dovrebbe
caricare in memoria una determinata parte del disco e poi il Program
Counter della CPU dovrebbe iniziare leggendo un determinato indirizzo
in memoria. Qualcuno mi saprebbe spiegare cosa avviene piů
dettagliatamente?
Esistono siti che trattano questi argomenti?
GRAZIE
Daniele.

 dettagliatamente?
Veramente a me risulta che la CPU vada, come prima cosa, a leggere le
istruzioni ad un determinato indirizzo e poi a quell'indirizzo ci trova
la ROM-BIOS con l'autodiagnostica e il loader di bootstrap che carica il
sistema operativo dal disco.
EMG

e affini, quindi cio' ti rendera' la ricerca + difficile.
Lo so anch'io che il mondo informatico si sta orientando verso altri
settori. Queste cose ti possono interessare solo se, come me, devi per
un esame fare un progettino mettendo su un dischetto qualcosa di
simile ad un piccolo sistema operativo. Non che debba avere
funzionalità da sistema operativo, mi basterebbe sapere ad esempio
esattamente dove devo collocare il codice nel dischetto...
Capito cosa mi serve? Mi puoi consigliare un link?
GRAZIE
Daniele.

Dammi maggiori info su cio' che devi realizzare.
La risposta è: 2). 
cioè devo realizzare un mini-mini-mini sistema operativo che parta AL
POSTO del DOS o di Windows95. 
Però dovresti spiegarmi (se non ti ho già seccato troppo) dove lo devo
mettere esattamente nel dischetto e come ce lo posso mettere (esistono
delle utility che mi consentono di scrivere dove cavolo voglio su un
dischetto non formattato?). 
Inoltre non capisco perchè dici che il 2) lo posso scrivere sia in
assembly che in C: a dirti la verità non so nemmeno se posso usare un
assemblatore, perchè ottengo un .EXE, che è un formato del DOS, e ha
un senso solo se ci fosse il DOS che lo esegue... (ricordo che il mio
programma deve girare AL POSTO del DOS o Windows...)
GRAZIE
Daniele.

croce? 8-)
A dire la verità un po' me la sono voluta...  ;-P
Non è che mi sapresti consigliare un sito su cui siano spiegate le
nozioni fondamentali che cerco? Come vedi sono abbastanza a digiuno di
queste cose...
GRAZIE
Daniele.

 permettere al DOS di creare un file system?
Sotto linux c'e' fdformat.  Comunque puoi anche permettere al DOS
di creare il suo file system, tanto dopo ci vai a scrivere sopra.
	Mauro

 formattazione dipendesse da SO a SO...
E' vero che ogni SO può formattare con un numero diverso di
tracce/settori per traccia/bytes per settore ma resta il fatto che senza
un qualche tipo di formattazione il dischetto è inutilizzabile in quanto
il drive ha bisogno almeno delle intestazioni dei settori per poterne
leggere i dati.
EMG


Il tuo programma deve essere composto da due sezioni
1) Programma che esegue il loader
2) Programma vero e proprio (il SO non è altro che un programma)
Il programma loader va messo nel settore 0 Fisico del dischetto
Il programma 2 in una locazione nota del disco (escluso il settore 0)
Non ho sottomano l'intera documentazione per cui non posso essere
scrupolosamente preciso.
Programma loader.
In genere tale programma è lungo 510 byte per i seguenti motivi si limita a
caricare altri settori del disco in memoria e a cedergli il controllo.
inoltre E' ASSOLUTAMENTE NECESSARIO che il 511 e 512 byte del settore 0
siano impostati ai valori 55 AA altrimenti non sara' mai riconosciuto come
settore valido.
gli indirizzi relativi all'interno del tuo codice devono partire da una base
= 0 (per esempio nei file com la base e' 100h)
esso verrà caricato in fase di avvio all'indirizzo 7C00:0000 (non lo ricordo
precisamente dovresti controllarlo)
la prima istruzione che viene eseguita è la 7C00:0000
Come avrai ben capito esso dovra' caricare tutti i settori occupati dal
programma 2 in memoria e poi cedergli i controllo in un modo ta te previsto.
Ricordati che non puoi accedere a nessuna funzione messa a disposizione
dagli int 21h, 26h, 25h ovvere gli int dos ma solo quelli del BIOS
So' gia' che sono stato poco chiaro
comunque illuminami sui punti in cui sono stato piu' oscuro
                ciao


Attenzione che in realtà il codice che serve per il boot sector è
veramente poco. Basta seguire tutte le regole del caso e alla fine
vedrai che non devi scrivere più di un centinaio di istruzioni
assembler.
Tutto quello che segue, cioè il caricamento del S.O. vero e proprio è
tutt'altro discorso.
Ciao. Spero di non essermi dilungato troppo.

Se riesci nell'impresa, non sarebbe una buona idea pubblicare i tuoi
risultati sulla Rete, con le opportune spiegazioni, in modo da aiutare altre
persone a fare cose simili?

 wrote:

Volentieri, se riesco. Se riesco a combinare qualcosa vorrei non solo
pubblicare i risultati, ma anche i sorgenti! 
Comunque ce ne vorrà ancora, di tempo...   :-(

comunque illuminami sui punti in cui sono stato piu' oscuro
Non sei tu che sei poco chiaro, sono io che ne so poco, perciò vi
prego di essere il più dettagliati possibile, magari con esempi
GRAZIE
Daniele


Ahem, se volete vi posso mandare il sorgente assembler di un boot
loader.
Praticamente basta compilarlo e copiarlo nel primo settore di un
dischetto (anzi, vi posso mandare anche il sorgente c++ che fa la copia
su dischetto).
Ciao.

assembly? ;-)
non vorrei sembrarti inopportuno, ma perchč invece di postarmi un
articolo contenente solo critiche inutili non mi dai qualche risposta?
Con questo post non hai dato nessuna informazione utile ne a me ne
agli altri frequentatori del NG! Se pensi che io voglia il listato del
programma, beh, non perdere tempo a rispondermi: risparmierai in
bolletta telefonica!
Daniele.

su dischetto).
Ecco finalmente qualcosa di utile: manda tutto, grazie.
Daniele.

Semplicemente perchè non ho abbastanza informazioni dovrei rinunciare?
[omissis]
Probabilmente il (presunto) tono delle critiche era un po' eccessivo,
comunque quello che si intendeva dire credo che riferisse al fatto che
dato che ti mancano diverse conoscenze sarebbe il caso che tu iniziassi
per gradi e con cose piu` semplici. Il solo fatto che tu abbia confuso
l'indirizzo di un jump con il fatto che l'istruzione del loader sia scritta nel
dischetto dimostra ad esempio che tu non abbia compreso bene
il meccanismo di boot e di non sapere che i programmi prima di essere
eseguiti vengono caricati dal disco in ram!
Per il resto puoi fare come vuoi, ma se vuoi evitare perdite di tempo ed
errori che ti portano fuori strada dovresti andare per gradi e studiare le
cose in ordine.
Saluti,
Paolo
------------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
  G: Per concludere, possiamo chiedervi di commentare
     l'attuale panorama informatico?
  I: /* l'attuale panorama informatico */
------------------------------------------------------------------

cose in ordine.
So già che ciò che sto per dire indurrà qualcun'altro a postare una
risposta simile a quella che ho criticato, ma io lo dico lo stesso:
Lo SO che un programma prima di essere eseguito viene caricato in
memoria (e il fatto che lo mettiate in dubbio mi offende pure!) quello
che non ho capito è: il boot sector non ha proprio l'aspetto di un
programma, in quanto, a parte i primi tre byte contenenti il jump, il
resto dovrebbe essere un insieme di informazioni sul disco etc...
(almeno la prima cinquantina di byte). Quindi vorrei sapere dove
cavolo va messo il codice vero e proprio nel disco. Per codice intendo
quello a cui poi, quando sarà caricato in memoria, salterà il jump che
si trova nei primi tre byte. Questo codice (sul disco) va forse messo
dopo la prima cinquantina di byte di cui sopra? Oppure va messo da
qualche altra parte?
E' chiaro che non ho compreso bene il meccanismo di boot (premetto che
io era questo che chiedevo fin dal primo post) perchè nessuno me l'ha
ancora spiegato! 
GRAZIE
Daniele.

ancora spiegato! 
Non so se ti puo' essere utile, ma perche' non ti guardi lilo come
funziona? E' un loader che si lancia da linux.
ftp://lrcftp.epfl.ch/pub/linux/local/lilo/lilo-21.tar.gz
--
(o-  T | Unix is simple and coherent , but it takes a genius  to understand
//\  U | and appreciate  its simplicity .
V_/_ X |                                    Dennis Ritchie .
email: r.salmaso (at) 
flashnet.it
 | pinguin (at)
linuxfan.com

 (almeno la prima cinquantina di byte).
Solo quelli (mi sembrano meno di una cinquantina ma non sono sicuro).
Il resto (tranne gli ultimi 2 byte - 0x55 e 0xAA) e' a disposizione
per metterci il programma.
Al boot l'intero boot sector (512 byte) viene caricato in memoria, e
viene eseguito a partire dall'inizio.  Siccome dopo i primi 3 byte
ci sono le informazioni, l'unica istruzione che ha senso mettere
all'inizio e' un salto in avanti che salta le informazioni e arriva
al grosso del programma.
	Mauro

memoria (e il fatto che lo mettiate in dubbio mi offende pure!)
Non era mia intenzione offenderti (e non lo e` tutt'ora), ma quando
confondi il fatto che sul disco ci sia scritto jmp QUALCOSA e poi
chiedi se quel qualcosa e` un indirizzo sul disco o meno...
Comunque per chiarirti ogni cosa...
1) All'avvio un programma residente su ROM (un loader) cerca un disco valido
per l'operazione di boot (supponiamo per semplicita` che trovi un floppy disk su
a)
2) Carica a partire da un preciso (prestabilito) indirizzo RAM (diciamo X) il boot sector e
come ultima istruzione salta all'indirizzo X
3) A questo punto il controllo e` posseduto dal loader che era scritto sul boot sector il
quale generalmente provvede ad eseguire il vero e proprio caricamento del s.o.
(o di un qualunque programma idoneo) e ad avviarne l'esecuzione. Per inciso
il loader del boot sector generalmente sa in quali settori fisici trovare i file giusti.
L'uso di un doppio loader (quello in ROM e quello su boot sector) e` necessario perche`
il loader su rom non ha conoscenza alcuna di quali file contendono il s.o. e anche per consentire
l'uso di s.o. diversi imponendo le minori restrizioni possibili.


bolletta telefonica!
TobiX

non saro' una tua vittima.
...non ti resta altro da fare se non levarti dai coglioni!
(Molti altri su questo NG mi hanno fatto capire le cose senza darmi
alcun listato. Evidentemente una cosa è conoscere e un'altra
spiegare.)

 wrote:



Accetto la critica perchè educata, però ti faccio notare che in quello
che ho scritto non ho mai riferito di non volere listati. Ritengo
infatti che A VOLTE siano più espliciti di qualunque spiegazione.
Fin'ora ho solo scritto:
"Se pensi che io voglia il listato del
programma, beh, non perdere tempo a rispondermi: risparmierai in
bolletta telefonica!"
con cui intendevo dire solo che se qualcuno ritiene che io non sia in
grado di capire farebbe meglio a smettere di postare articoli a questo
thread (offensivi o di spiegazione) così non perderebbe tempo...
Con sollievo di molti dirò anche che ormai ho le idee chiare
sull'argomento, pur NON AVENDO VISTO ANCORA UN LISTATO!
Ciao
Daniele.


Data la brevità del codice, ho deciso di postarlo direttamente nella
lettera.
Secondo me, spesso è molto utile avere un esempio scritto funzionante
oltre che a spiegazioni "teoriche" senza alcun spezzone di codice.
Dato che comunque il codice di un boot sector sono solo poche linee di
codice (nel listato sono le prime 75 linee che contano), credo sia
meglio postare un qualcosa di funzionante da cui prendere spunto (o
copiare spudaratamente, nel qual caso cmq non si otterrebbe nulla)
piuttosto che (o a assieme) centinaia di consigli che magari spesso
confondono più che aiutare.
Personalmente, a me capita spesso di dovermi fidare della documentazione
(anche per esempio di doc. riguardante le api di win32) e perdere ore
solo per capire come buttare giù correttamente una decina di istruzioni.
Spesso se avessi un esempio risolverei il problema in 10 minuti.
Per cui, nella speranza che possa essere utile, ecco il listato di un
boot sector:
COMMENT
#-------------------------------------------------------------------->
<<-----------------------------* INTESTAZIONE
*----------------------------->>
PROGRAMMATORE   : Nicola Zanaga
FILE            : boot.asm
TIPO PROGRAMMA  : programma di boot
VERSIONE        : 1.00
DATA CREAZIONE  : 9 - 3 - 1996
ULTIMA MODIFICA :
NOTE            : si incarica di visualizzare un messaggio, di caricare
nella
                  posizone 5000h:0000h il kernel. Il kernel deve
trovarsi
                  nel primo cilindro, iniziare dal primo settore del
                  cilindro, sulla faccia 0 del drive A.
                  Può essere lungo 65000 byte
COMMENTI        :
<-----------------------------------------------------------------------
-----#
  ; definisci modello di memoria (prima di ogni altra dichiarazione)
  .MODEL   SMALL, PASCAL
;
*-----------------------------------------------------------------------
-* ;
; << DEFINIZIONE DI STRUTTURE E COSTANTI >> ;
;
*-----------------------------------------------------------------------
-* ;
;
*-----------------------------------------------------------------------
-* ;
; << DATI >> ;
;
*-----------------------------------------------------------------------
-* ;
;
*-----------------------------------------------------------------------
-* ;
; << CODICE >> ;
_TEXT                   SEGMENT  USE16
  ASSUME   CS: _TEXT, DS: _TEXT
  LOCALS   @@
  .386C
  Iniz                  LABEL WORD
  jmp      flush
  DB       40 DUP(0)  ; for boot information
flush:
  call     NEAR PTR EvaluateIP
  Fin                   LABEL WORD
EvaluateIP:
  pop      BX
  sub      BX , (OFFSET Fin - OFFSET Iniz)
    ; spiazzamento, da aggiungere a riferimenti assoluti (OFFSET,
VARIABILI)
  cli
  cld
  push     CS
  pop      DS
  mov      SI , OFFSET Msg
  add      SI , BX
@@Cicle:
  lodsb
  or       AL , AL
  jz       @@LoadKernel
  call     PutCh
  jmp      @@Cicle
@@LoadKernel:
  mov      SI , OFFSET ErrMsg
  add      SI , BX
  mov      AH , 2                 ; lettura
  mov      AL , 18                ; numero settori
  mov      CH , 1                 ; cilindro
  mov      CL , 1                 ; settore di partenza
  mov      DL , 0                 ; drive a,
  mov      DH , 0                 ; faccia 0
  mov      BX , 5000h
  mov      ES , BX
  xor      BX , BX                ; buffer 5000h:0000h
  int      13h
  jc       @@CicleErr
  mov      AH , 2                 ; lettura
  mov      AL , 18                ; numero settori
  mov      CH , 1                 ; cilindro
  mov      CL , 1                 ; settore di partenza
  mov      DL , 0                 ; drive a,
  mov      DH , 1                 ; faccia 1
  mov      BX , 5000h + 18*512
  mov      ES , BX
  xor      BX , BX                ; buffer 5000h:0000h
  int      13h
  jc       @@CicleErr
  jnc      @@GoKernel
@@CicleErr:                       ; mostra messaggio di errore
  lodsb
  or       AL , AL
  jz       @@Halt
  call     PutCh
  jmp      @@CicleErr
@@Halt:
  cli
  hlt
@@GoKernel:
  push     5000h
  push     0000h
  retf                            ; salta al kernel
PutCh                   PROC
; AL -> carattere
  push     AX  BX  DX  DS
  mov      DX , 0B800h
  mov      DS , DX
  mov      BX , AX
  mov      DX , 3D4h
  mov      AL , 0Eh
  out      DX , AL
  inc      DX
  in       AL , DX
  mov      AH , AL
  dec      DX
  mov      AL , 0Fh
  out      DX , AL
  inc      DX
  in       AL , DX
  xchg     BX , AX  ; AL -> carattere, BX -> pos cursore
  cmp      AL , 13
  je       @@Skip
  shl      BX , 1
  mov      BYTE PTR DS:[BX] , AL
  shr      BX , 1
@@Skip:
  inc      BX
  cmp      AL , 13
  jne      @@NoNL
  add      BX , 79
  mov      AX , BX
  xor      DX , DX
  mov      BX , 80
  div      BX
  imul     AX , 80
  mov      BX , AX
@@NoNL:
  mov      DX , 3D4h
  mov      AL , 0Fh
  out      DX , AL
  inc      DX
  mov      AL , BL
  out      DX , AL
  dec      DX
  mov      AL , 0Eh
  out      DX , AL
  inc      DX
  mov      AL , BH
  out      DX , AL
  pop      DS  DX  BX  AX
  ret
ENDP
  Msg                   DB 13
                        DB 'System  by Zanaga Nicola:', 13
                        DB 'NON SPACCIATELO PER VOSTRO!', 13
                        DB 'Loading kernel. Please wait...', 13, 0
  ErrMsg                DB 'Error loading kernel. System halted', 13, 0
_TEXT                   ENDS
;
*-----------------------------------------------------------------------
-* ;
END
Ecco il listato per scrivere il boot sector sul dischetto:
#include <io.h>
char bootsec[512];
char boot1[512];
void readboot(void) {
  for (int retry = 0; retry < 3; retry++) {
    asm {
     mov     ax, 0x201
     mov     cx, 1
     mov     dx, 0
     push    cs
     pop     es
     mov     bx, OFFSET bootsec
     int     0x13
    };
  };
};
void writeboot(void) {
  for (int retry = 0; retry < 3; retry++) {
    asm {
     mov     ax, 0x301
     mov     cx, 1
     mov     dx, 0
     push    cs
     pop     es
     mov     bx, OFFSET boot1
     int     0x13
    };
  };
};
void main()  {
  int h = _open("boot.exe", 0);
  lseek(h, 512, SEEK_SET);
  _read(h, boot1, 512);
  readboot();
  for(int i=0; i<40; i++)  boot1[i+3] = bootsec[i+3];
  writeboot();
};
E non chiedetemi di postarvi anche il codice di kernel, che tanto questo
non ve lo posto :-)