Operációs rendszerek Klasszikus UNIX (Bevezetés, általánosságok)
1
Történet • 1969 Bell Research Lab –korábban az MIT-vel Multics –Ken Thompson, Dennis Ritchie
• 1973 implementáció DEC DPD-11-en –C progromozási nyelv (platform függetlenség)
• 1977 kb. 500 helyen használják –egyetemeknek ingyenesen hozzáférhet! forráskód
• 1980 DARPA TCP/IP protokoll • 1984 TCP/IP beépített támogatása a BSD UNIXban 2
UNIX család
3
A UNIX szerkezete
4
Rendszerhívások és kernel végrehajtás • Rendszerhívás interfész –privilégizált módba (teljes hozzáférés a rendszer er!forrásokhoz) váltás ellen!rzött körülmények között –kernel végrehajtás “procedurálisan” –kernel nem preemptív (egy processzoros gépekre tervezték) • de expliciten végrehajthat blokkoló utasítást (pl. I/O) • és interrupt megszakíthatja, a kiszolgálás után a vezérlés a megszakított folyamathoz kerül vissza (user módban dönthet másképp is az ütemez!) 5
Eszközkezelés (device handling) • Két féle eszközkezelés –block I/O (pl. disk) –character I/O (pl. terminal)
• Nincsenek dedikált eszközkezel! folyamatok –interrupt, privilégizált mód, interrupt handler hívása
• Eszköz meghajtók (device drivers) –top half (I/O modul által hívható) –bottom half (interrupt kezel! által hívható)
6
Fájlrendszer [részletek kés!bb] • Hierarchikus fájlrendszer névtér –könyvtárfájlok (directory) –egy gyöker" –fájlrendszerek becsatolása (mount)
• Speciális fájlok –eszközök, IPC mechanizmusok normál fájlokéval azonos interfészen érhet!k el
• Fájlrendszer interfész –I/O m"veletek • megnyitás, lezárás, olvasás, írás, pozicionálás, létrehozás
7
Folyamatok kezelése • Folyamatok címtere –saját logikai címtér (felhasználói, kernel)
8
Folyamatok kezelése (folyt.) • Folyamatok létrehozása –fork rendszerhívás • új címtér a hívó replikája, új process adatszerk.
–exec... rendszerhívás • program betöltése az új címtérbe (Text), Data újra létrehozása
–exit rendszerhívás • címtér megszüntetése, visszatérési kód, process adatszerk. marad (zombi állapot)
–wait rendszerhívás • szinkronizálás a gyerek halálára
9
Folyamat hierarchia (pl.)
10
Folyamatok ütemezése [részletek kés!bb] • Dinamikus prioritás alapú ütemezés –kernel végrehajtás magasabb prioritású –blokkolt folyamat prioritását a várt esemény határozza meg –user folyamatok id!szeleteket kapnak, roundrobin ütemezés • dinamikus prioritás a felhasznált id! alapján
11
Folyamatok állapotai
12
Folyamatok környezete • Minden adat, ami szükséges a folyamat újraindításához. • Két vezérlési adatstruktúra: –proc (processz) struktúra a rendszer memóriájában: • a kernel az összes folyamat proc struktúrájához hozzáfér, • tárolás: hash tábla,
–u area (user area, felhasználói terület): a processz memóriájában, de csak (!) kernel módban módosítható: • a kernel csak a futó folyamat u area-jához fér hozzá közvetlenül, • indirekt módon a többit is eléri, de jóval lassabban.
13
A proc struktúra • Processz azonosító (PID). • User area-ra mutató referencia. • Processz állapota: – pl.: kernel vagy user módban fut, várakozó vagy futásra kész (állapot diagram).
• Ütemezési információk: – pl.: p_cpu, p_usrpri.
• Ütemezésnél használt egyéb mutatók: – pl.: milyen prioritási kategóriában van.
• Signalok kezelésére vonatkozó információ: – ignored-blocked-posted-handled.
• MMU információ: – milyen MMU regisztereket kell frissíteni a folyamat futtatásakor.
14
struct proc (pl. FreeBSD) struct! proc { ! TAILQ_ENTRY(proc) p_procq;! /* run/sleep queue. */ ! LIST_ENTRY(proc) p_list;! /* List of all processes. */ ! /* substructures: */ ! struct! pcred *p_cred;! ! /* Process owner's identity. */ ! struct! filedesc *p_fd;! ! /* Ptr to open files structure. */ ! struct! pstats *p_stats;! /* Accounting/statistics (PROC ONLY). */ ! struct! plimit *p_limit;! /* Process limits. */ ! struct! vm_object *p_upages_obj;/* Upages object */ ! struct! procsig *p_procsig; #define p_sigacts! p_procsig->ps_sigacts #define p_sigignore! p_procsig->ps_sigignore #define p_sigcatch!p_procsig->ps_sigcatch #define! p_ucred! ! p_cred->pc_ucred #define! p_rlimit!p_limit->pl_rlimit ! ! !
int! p_flag;! ! char!p_stat;! ! char!p_pad1[3];
! !
/* P_* flags. */ /* S* process status. */
! pid_t! p_pid;! ! ! /* ! LIST_ENTRY(proc) p_hash;! /* ! LIST_ENTRY(proc) p_pglist;! /* */ ! struct! proc *p_pptr;! ! /* */ ! LIST_ENTRY(proc) p_sibling;!/* */ ! LIST_HEAD(, proc) p_children;! children. */ ! ! ! !
Process identifier. */ Hash chain. */ List of processes in pgrp. Pointer to parent process. List of sibling processes. /* Pointer to list of
struct callout_handle p_ithandle; /* ! ! ! ! * Callout handle for scheduling ! ! ! ! * p_realtimer. ! ! ! ! */
15
struct proc (pl. FreeBSD, folyt.) /* The following fields are all zeroed upon creation in fork. */ #define! p_startzero! p_oppid ! XXX ! XXX !
pid_t! p_oppid;! /* Save parent pid during ptrace. */ int! p_dupfd;! /* Sideways return value from fdopen. */ struct!
vmspace *p_vmspace;!
/* Address space. */
! /* scheduling */ ! u_int! p_estcpu;! /* Time averaged value of p_cpticks. */ ! int! p_cpticks;! /* Ticks of cpu time. */ ! fixpt_t! p_pctcpu;! /* %cpu for this process during p_swtime */ ! void!*p_wchan;! /* Sleep address. */ ! const char *p_wmesg;! /* Reason for sleep. */ ! u_int! p_swtime;! /* Time swapped in or out. */ ! u_int! p_slptime;! /* Time since last blocked. */ ! struct! itimerval p_realtimer;!/* Alarm timer. */ ! u_int64_t p_runtime;! ! /* Real time in microsec. */ ! u_int64_t p_uu;! ! ! /* Previous user time in microsec. */ ! u_int64_t p_su;! ! ! /* Previous system time in microsec. */ ! u_int64_t p_iu;! ! ! /* Previous interrupt time in usec. */ ! u_int64_t p_uticks;! ! /* Statclock hits in user mode. */ ! u_int64_t p_sticks;! ! /* Statclock hits in system mode. */ ! u_int64_t p_iticks;! ! /* Statclock hits processing intr. */
! !
09410 09411 stack frame 09412 09413 09414 and limit*/ 09415 and data */ 09416 protect.h */ 09417 09418 09419 09420 09421 09422 09423 _rpr *) */ 09424 09425 image */ 09426 */ 09427 09428 09429 set */ 09430 09431 */ 09432 */ 09433 09434 09435 09436 09437 09438 access) */ 09439
int! p_traceflag;! ! /* Kernel trace points. */ struct! vnode *p_tracep;! /* Trace to vnode. */
09410 09410 09411 09411 frame */ frame 09412*/ 09412 ! struct! vnode *p_textvp;! /* Vnode of executable. */ 09413 09413 09414 09414 ! char!p_lock;! ! ! /* Process lock (prevent swap) limit*/ limit*/ count. */ 09415 09415 ! u_char! p_oncpu;!! /* Which cpu we are on */ data */ data */ ! u_char! p_lastcpu;! ! /* Last cpu we were on */ 09416 09416 ! char!p_rqindex;! ! /* Run queue index */ */ */09417 09417 ! short! p_locks;!! /* DEBUG: lockmgr count of held 09418 09418 locks */ 09419 ! short! p_simple_locks;! ! /* DEBUG: count of held 09419 09420 09420 simple locks */ 09421 09421 ! unsigned int! p_stops;!/* procfs event bitmask */ 09422 09422 ! unsigned int! p_stype;!/* procfs stop event type */ 09423 09423 ! char!p_step;! ! ! /* procfs stop *once* flag */ *) */ *) */ ! unsigned char!p_pfsflags;! /* procfs flags */ 09424 09424 ! char!p_pad3[2];! ! /* padding for alignment */ 09425 09425 ! register_t p_retval[2];! ! /* syscall aux returns */ */ */09426 ! struct! sigiolst p_sigiolst;! /* list of sigio 09426 sources */ 09427 09427 ! int! p_sigparent;! ! /* signal to parent on exit */ 09428 09428 ! sigset_t p_oldsigmask;!! /* saved mask from before 09429 09429 sigpause */ */ */ ! int! p_sig;! ! ! /* for core dump/debugger XXX */ 09430 09430 u_long! p_code;! ! /* for core dump/ 09431 09431 debugger XXX */ 09432 09432 ! struct! klist p_klist;! ! /* knotes attached to 09433 09433 this process */ 09434 09434 09435 09435 /* End area that is zeroed on creation. */ 09436 09436 09437 09437 09438 16 09438 */ */09439 09439 09440 09440 task */ task */ ! sigset_t p_siglist;! delivered. */
!
/* Signals arrived but not
struct proc (pl. FreeBSD, folyt.) /* The following fields are all copied upon creation in fork. */ #define! p_startcopy! p_sigmask ! sigset_t p_sigmask;! /* Current signal mask. */ ! stack_t! p_sigstk;!/* sp & on stack state variable */ ! u_char! p_priority;! /* Process priority. */ ! u_char! p_usrpri;!/* User-priority based on p_cpu and p_nice. */ ! char!p_nice;! ! /* Process "nice" value. */ ! char!p_comm[MAXCOMLEN+1]; !
! struct proc *p_leader; ! struct! pasleep p_asleep;! /* Used by asleep()/ await(). */ ! void!*p_emuldata;! /* process-specific emulator state data */ };
struct ! pgrp *p_pgrp;!/* Pointer to process group. */
! struct ! sysentvec *p_sysent; /* System call dispatch information. */ ! struct! rtprio p_rtprio;! /* Realtime priority. */ ! struct! prison *p_prison; ! struct! pargs *p_args; /* End area that is copied on creation. */ #define! p_endcopy!p_addr ! struct! user *p_addr;!/* Kernel virtual addr of u-area (PROC ONLY). */ ! struct! mdproc p_md;! /* Any machine-dependent fields. */ ! u_short! p_xstat;!/* Exit status for wait; also stop signal. */ ! u_short! p_acflag;!/* Accounting flags. */ ! struct! rusage *p_ru;!/* Exit information. XXX */ ! */ ! ! !
int! p_nthreads;!
/* number of threads (only in leader)
void!*p_aioinfo;! /* ASYNC I/O info */ int! p_wakeup;!/* thread id */ struct proc *p_peers;!
09410 09410 09411 09411 frame */ frame 09412*/ 09412 09413 09413 09414 09414 limit*/ limit*/ 09415 09415 data */ data */ 09416 09416 */ */09417 09417 09418 09418 09419 09419 09420 09420 09421 09421 09422 09422 09423 09423 *) */ *)09424 */ 09424 09425 09425 */ */09426 09426 09427 09427 09428 09428 09429 09429 */ */09430 09430 09431 09431 09432 09432 09433 09433 09434 09434 09435 09435 09436 09436 09437 09437 09438 17 09438 */ */09439 09439 09440 09440 task */ task */
proc table kezelése (pl. FreeBSD) 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
struct proc * pfind(pid) register pid_t pid; { register struct proc *p; sx_slock(&allproc_lock); LIST_FOREACH(p, PIDHASH(pid), p_hash) if (p->p_pid == pid) { PROC_LOCK(p); break; } sx_sunlock(&allproc_lock); return (p); }
#define PIDHASH(pid) pidhash])
378 int i; 379 380 if (elements <= 0) 381 panic("hashinit: bad elements"); 382 for (hashsize = 1; hashsize <= elements; hashsize <<= 1) 383 continue; 384 hashsize >>= 1; 385 hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK); 386 for (i = 0; i < hashsize; i++) 387 LIST_INIT(&hashtbl[i]); 388 *hashmask = hashsize - 1; 389 return (hashtbl); 390 }
(&pidhashtbl[(pid) &
124 pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash); 373 void * 374 hashinit(int elements, struct malloc_type *type, u_long *hashmask) 375 { 376 long hashsize; 377 LIST_HEAD(generic, generic) *hashtbl;
18
A user area • Egyszer" adatelemek: – PCB (hardver környezet, regiszterek). – Mutató a folyamat proc struktúrájára. – Jogosítványok (valós {signal} és hatásos {file} UID, GID). – Signal handler (kezel!) rutinok címei. – CPU használati statisztika (ütemezéshez). – Környezeti változók (pl.: aktuális könyvtár, kontroll terminál, keresési út).
• Összetett adatelemek: – A folyamathoz tartozó memória (a felhasználói címtartomány) elérésére szolgáló táblázat (címtranszformációs tábla, perprocess Region Table). – File-leírók táblázata (per process File Descriptor Table). – Kernel módban használt veremtár (per process Kernel Stack).
19
u-area (pl. FreeDSB) /* * Per process structure containing data that isn't needed in core * when the process isn't running (esp. when swapped out). */ struct! user { ! struct! pcb u_pcb; ! struct! sigacts u_sigacts;!/* p_sigacts points here (use it!) */ ! struct! pstats u_stats;! ! /* p_stats points here (use it!) */ ! /* ! * Remaining fields for a.out core dumps - not valid at other times! ! */ ! struct! kinfo_proc u_kproc;! /* proc + eproc */ ! struct! md_coredump u_md;! /* machine dependent glop */ };
40 struct pcb { 41 register_t 42 register_t 43 register_t 44 register_t 45 register_t 46 struct 47 struct 48 faultbuf 49 50 int 51 #define PCB_FPU 52 struct fpu { 53 double 54 double 55 } pcb_fpu; 56 unsigned int 57 58 };
pcb_context[20]; pcb_cr; pcb_sp; pcb_lr; pcb_usr; pmap *pcb_pm; pmap *pcb_pmreal; *pcb_onfault;
/* non-volatile r14-r31 */ /* Condition register */ /* stack pointer */ /* link register */ /* USER_SR segment register */ /* pmap of our vmspace */ /* real address of above */ /* For use during copyin/copyout */
user struct
pcb struct
pcb_flags; 1 /* Process had FPU initialized */ fpr[32]; fpscr; /* FPSCR stored as double for easier access */ /* Floating point processor */ pcb_fpcpu; /* which CPU had our FPU stuff. */
20
Daemon folyamatok • Önálló folyamatokként megvalósított OPR funkciók. • Nem privilegizált módban futnak. • Rendszerhívásokon keresztül érik el a kernel szolgáltatásait. • Nincsenek terminálhoz kötve
21
IPC megoldások • Csövek (pipe) –fájl és eszköz I/O-val kompatibilis –egyirányú kommunikációt (író, olvasó) biztosító bájt folyam –szinkronizál a folyamatok között • üres cs!b!l olvasó folyamat blokkolódik • csövet (puffert) “teleíró” folyamat blokkolódik
–a gyerekfolyamat örökli !ket (a többi fájl leíróhoz hasonlóan) 22
IPC megoldások (folyt.) • Signal –el!re definiált szemantika (folyamat vezérlés, hibakezelés) –nincs szinkronizálás –elveszhetnek –kernel módba lépéskor detektálhatók
23