MC504/MC514 - Sistemas Operacionais
Implementação de Chamadas de Sistema
Ambiente de testes
QEMU
O QEMU é um virtualizador
e emulador de processadores. Podemos fazer um teste bem simples com o
QEMU utilizando
a imagem
disponível em Testing
QEMU .
qemu-system-i386 -hda linux-0.2.img
Teste com o kernel 4.5.3
Atenção: como estes arquivos são muito
grandes, caso os testes sejam feitos no laboratório deveremos utilizar o diretório /tmp das
máquinas.
- Obtenha a versão 4.5.3 ou outra verão recente do kernel em kernel.org. Execute a descompactação com o comando:
$ tar xJvf linux-4.5.3.tar.xz
- Obtenha a imagem mc504.img que foi criada
por Glauber de Oliveira Costa para a turma do 1s2008
de sistemas operacionais.
- Obtenha o arquivo de configuração config-linux-4.5.3 adequeado para rodar com o QEMU.
- Para não ter problemas com a quota, configure previamente
o diretório CCACHE utilizando o comando:
$ export CCACHE_DIR="/tmp/.ccache"
- Substitua o arquivo de configuração e compile o kernel.
$ cd linux-4.5.3
$ mv config-4.5.3 .config
$ make -j 5 ARCH=i386
- Teste o kernel com a imagem utilizando o QEMU:
$ qemu-system-i386 -hda mc504.img -kernel linux-4.5.3/arch/i386/boot/bzImage -append "ro root=/dev/hda"
- Quando o sistema entrar poderemos fazer login com
usuário: root
senha: root
Primeira chamada
Antes de fazermos uma chamada de sistema mais elaborada, vamos testar
uma que não recebe parâmetros e retorna uma
constante. Chamaremos esta chamada de mycall.
- Alterar a
tabela linux-4.5.3/arch/x86/entry/syscalls/syscall_32.tbl,
acrescentando uma nova linha ao final do arquivo:
378 i386 mycall sys_mycall
- Incluir uma declaração da
função sys_mycall
em um ponto adequado do arquivo linux-4.5.3/include/linux/syscalls.h
asmlinkage long sys_mycall(void);
- Incluir o código para função no
diretório linux-4.5.3/arch/x86/kernel/. Podemos utilizar o
arquivo mycall.c, cujo conteúdo é:
#include <linux/unistd.h>
#include <linux/linkage.h>
asmlinkage long sys_mycall(void) {
return(4096);
}
- Alterar o Makefile do
diretório linux-4.5.3/arch/x86/kernel/, incluindo uma linha:
obj-y += mycall.o
- No diretório linux-4.5.3 executar
$ make -j 5 ARCH=i386
- Escrever um programa para testar a chamada em modo
usuário. Pode ser um programa bem simples
como ex-mycall.c:
/*
* Teste da nova chamada de sistema
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int r = syscall(378);
printf("Retorno da chamada de sistema: %d.\n", r);
return r;
}
- Compilar o programa, considerando que a imagem foi feita para
i386. As opções são:
- Rodar o programa no QEMU:
Devemos tornar o executável disponível no ambiente do QEMU.
- Uma opção simples é exportar o arquivo que conté o executá como um disco:
$ qemu-system-i386 -hda mc504.img -kernel linux-3.12/arch/i386/boot/bzImage \
-append "ro root=/dev/hda" -hdb ex-mycall
Após logar no sistema, devemos executar:
$ cat /dev/hdb > ex-mycall
$ chmod +x ex-mycall
$ ./ex-mycall
Tarefa
Você deverá implementar uma chamada de sistema que receba
pares de chave/valor. A chave deve ser um parâmetro inteiro e o valor uma cadeia de caracteres. Crie um par
de chamadas de sistema getkey e setkey para
armazerar e recuperar estes pares de chave/valor. Você
precisará fazer também uma programa em C para testar as
suas novas chamadas de sistema.
Por que as funções como get_user
e put_user ou copy_to_user e copy_from_user
são necessárias? Veja a introdução User space memory access from the Linux kernel. Versão em português: Acesso à memória do espaço do usuário a partir do kernel Linux.
Entrega: 19 de maio
Os grupos que entregarem o código das chamadas de sistema, com um arquivo README justificando o uso das funções citadas acima via Moodle poderão ganhar até um ponto na prova 3.