Ulazno/Izlazni Podsistem
Elektrotehnički fakultet
Operativni sistemi 1
u Beogradu
Ulazno/Izlazni Podsistem (IO)
Sl.1. Hard disk
Sl2. Logička slika hard diska
Zad 1.
Jun 2005.
Potrebno je realizovati drajver (
device driver
) za jedan izlazni, znakovno
orijentisani uređaj, pri čemu korisnički proces može zadati prenos čitavog niza
znakova koje će DMA upisivati na uređaj znak po znak. Korisnički proces koji
zadaje izlaznu operaciju svoj zahtev predstavlja sledećom strukturom:
struct DeviceRequest {
char* block; // Pokazivač na niz znakova koje treba preneti na uređaj
unsigned long size; // Veličina niza znakova
Semaphore* toSignal; // Semafor koji treba signalizirati po završetku op.
};
Korisnički proces svoj zahtev zapisan u ovakvoj strukturi upisuje u ograničeni
bafer koji predstavlja red postavljenih zahteva, a potom se blokira na semaforu
na koji ukazuje pokazivač
toSignal
. Semafor je standardni, brojački semafor
sa uobičajenim operacijama
signal
i
wait
. Ograničenom baferu pristupa se
sledećim operacijama koje su blokirajuće ukoliko je bafer pun, odnosno
prazan:
void putDeviceRequest (DeviceRequest*); // Stavlja jedan zahtev u red
DeviceRequest* getDeviceRequest(); // Uzima jedan zahtev iz reda
Sama izlazna operacija obavlja se preko DMA uređaja kome se prenos niza
znakova
block
veličine
size
iz memorije na uređaj zadaje i pokreće sledećom
neblokirajućom operacijom:
void DMARequest (char* block, unsigned long size);
Kada završi prenos bloka podataka, DMA generiše prekid kome pripada ulaz
10h u vektor tabeli.
Korišćenjem navedenih operacija (za koje se pretpostavlja da su
implementirane) i već realizovanih koncepta događaja i niti, sa interfejsima
Operativni sistemi 1 Copyright
2006 Miloš Milovanović Maj
2006
1 / 13
Elektrotehnički fakultet
Operativni sistemi 1
u Beogradu
kao što je definisano projektnim zadatkom za domaći rad, napisati kompletan
kod ovog drajvera uređaja.
Rešenje:
#include "event.h"
#include "thread.h"
extern DeviceRequest* getDeviceRequest();
extern void DMARequest (char* block, unsigned long size);
void interrupt deviceInt (...);
Event deviceEvent(0x10,deviceInt);
void interrupt deviceInt (...) {
deviceEvent.signal();
}
class DeviceDriver : public Thread {
protected:
DeviceDriver () : Thread() { start(); }
virtual void run ();
private:
static DeviceDriver instance;
};
DeviceDriver DeviceDriver::instance;
void DeviceDriver::run () {
while (1) {
DeviceRequest* dr = getDeviceRequest();
DMARequest(dr->block,dr->size);
deviceEvent.wait();
dr->toSignal->signal();
}
}
Zad 2.
Implementirati bibliotečnu funkciju
void print(char* str)
koja štampa niz
karatkera
str
, na znakovno orijentisani uređaj opisan u prethodnom zadatku,
kojisteći drajver implementiran takođe u prethodnom zadatku. Funkcija treba
da bude blokirajuća i bezbedna za rad u okruženju sa više niti (
reentrand
,
odnosno
thread-safe
).
Rešenje:
Operativni sistemi 1 Copyright
2006 Miloš Milovanović Maj
2006
2 / 13

Elektrotehnički fakultet
Operativni sistemi 1
u Beogradu
ulazu
N
poziva funkciju
ExternalEvent::interruptOccurrence(int)
sa
argumentom koji predstavlja taj broj ulaza.
Rešenje:
// ExternalEvent.h
void int_mask();
void int_unmask();
const int NumOfInterruptEntries = ... ; // Number of interrupt entries
class ExternalEvent {
public:
ExternalEvent(int interruptNo);
void wait();
static void interruptOccurrence(int interruptNo);
protected:
void signal ();
void block ();
void deblock ();
~ExternalEvent();
static ExternalEvent* events[NumOfInterruptEntries];
private:
int val, intNo;
Queue blocked;
};
// ExternalEvent.cpp
ExternalEvent::ExternalEvent(int interruptNo) : val(0),
intNo(interruptNo){
if (intNo>=0 && intNo<NumOfInterruptEntries) {
int_mask();
// add the event to the event list
events[intNo]=this;
int_unmask();
}
}
ExternalEvent::~ExternalEvent(){
int_mask();
Operativni sistemi 1 Copyright
2006 Miloš Milovanović Maj
2006
4 / 13
Ovaj materijal je namenjen za učenje i pripremu, ne za predaju.
Slični dokumenti