Acá solo haré los ejercicios de programación (a partir del 9).

Ejercicio 9

Se puede resolver accediendo al directorio “..” y buscar qué directorio en esa lista de directorios lo lleva nuevamente al /home. No lo programo ya que no es muy interesante el ejercicio.

Ejercicio 10

typedef struct estructura_entrada_directorio {
	char name[];
	size_t fat_entry;
	unsigned int name_length;
	
	// OPCIONALES
	unsigned char file_type; // Asumo que no hay directorio y archivo en mismo directorio que se llaman igual
	unsigned char file_size;
	
} dir_t;

char* read_file(dir_t dir_entry) {
	char* buffer = malloc(dir_entry.file_size);
	size_t fat_entry = dir_entry.fat_entry;
	buffer.append(read_blocks(fat_entry));
	do {
		fat_entry = FAT_entry(fat_entry);
		buffer.append(read_blocks(fat_entry));
	} while(fat_entry != FAT_entry(fat_entry));
	return buffer;
}

char* cargar_archivo(char* directorios[]) {
	char* raw_data = root_table();
	for (auto directorio : directorios) {
		dir_t curr_dir = parse_directory_entries(raw_data);
		for (auto dir : curr_dir) {
			if (directorio == dir.name) {
				free(raw_data);
				raw_data = read_file(dir);
			}
		}
	}
	return raw_data;
}

Ejercicio 11

char input_mem[3][100];
char buffer_lectura[3][1000];
atomic_int buffer_start[3];
atomic_int buffer_end[3];
boolean procesos_activos[3];

mutex mut_procesos[3];
// Asumo mutex si se hace singal y ya es 1 se mantiene en 1
sem sem_open_close = sem(1);

void handle_key_down() {
	int val = read(KEYB_REG_DATA);
	char ascii_char = keycode2ascii(val & 11111111111111);
	int id = (val >> 14) & 11;
	if (id == 0) {
		if (write_to_all_buffers(ascii_char)) {
			mut_procesos[0...2].signal()
			OUT(KEYB_REG_CONTROL, READ_OK);
		} else {
			OUT(KEYB_REG_CONTROL; READ_FAILED);
		}
	} else {
		id--;
		if (write_to_buffer(id, ascii_char)) {
			_procesos[id].signal()
			OUT(KEYB_REG_CONTROL, READ_OK);
		} else {
			OUT(KEYB_REG_CONTROL; READ_FAILED);
		}
	}
	
}

void driver_load() {
	// Se corre al cargar el driver al kernel.
	mem_map(INPUT_MEM_0, input_mem[0], 100);
	mem_map(INPUT_MEM_1, input_mem[1], 100);
	mem_map(INPUT_MEM_2, input_mem[2], 100);
	request_irq(IRQ_KEYB, handle_key_down);
}

void driver_unload() {
	// Se corre al eliminar el driver del kernel.
	mem_unmap(INPUT_MEM_0);
	mem_unmap(INPUT_MEM_1);
	mem_unmap(INPUT_MEM_2);
	free_irq(IRQ_KEYB);
}

int driver_open() {
	// Debe conectar un proceso, asignandole un ID y retornandolo,
	// o retornando -1 en caso de falla.
	sem_open_close.wait();
	// Sincronizo la apertura y cierre para que dos procesos no se asignen
	// a la misma posición.
	int id = -1;
	for (int i = 0; i < 3; i++) {
		if (!procesos_activos[i]) {
			id = i;
			procesos_activos[i] = true;
			OUT(KEYB_REG_AUX, i);
			OUT(KEYB_REG_STATUS, APP_UP);
		}
	}
	sem_open_close.signal();
	return id;
}

void driver_close(int id) {
	// Debe desconectar un proceso dado por parametro.
	sem_open_close.wait();
	OUT(KEYB_REG_AUX, id);
	OUT(KEYB_REG_STATUS, APP_DOWN);
	procesos_activos[i] = false;
	sem_open_close.signal();
}

int driver_read(int id, char* buffer, int length) {
	// Debe leer los bytes solicitados por el proceso ’’id’’
	while (get_buffer_length(id) < lenght) {
		mut_procesos[id].wait();
	}
	
	copy_from_buffer(id, buffer, length);
	return length;
}

int driver_write(char* input, int size, int proceso) {
	copy_from_user(input_mem[proceso], input, size);
	return size;
}