Instituto de Computação - UNICAMP

MC504/MC514 - Sistemas Operacionais

Implementação de Chamadas de Sistema

Islene Calciolari Garcia

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.
  1. 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 
    
  2. Obtenha a imagem mc504.img que foi criada por Glauber de Oliveira Costa para a turma do 1s2008 de sistemas operacionais.
  3. Obtenha o arquivo de configuração config-linux-4.5.3 adequeado para rodar com o QEMU.

  4. Para não ter problemas com a quota, configure previamente o diretório CCACHE utilizando o comando:
    $ export CCACHE_DIR="/tmp/.ccache"
    
  5. 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    
      
  6. 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" 
    

  7. 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.
  1. 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
    
  2. 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);
    
  3. 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);
    }
    
  4. Alterar o Makefile do diretório linux-4.5.3/arch/x86/kernel/, incluindo uma linha:
    obj-y                                   += mycall.o
    
  5. No diretório linux-4.5.3 executar
      $ make -j 5 ARCH=i386
      
  6. 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;
    }
    
  7. Compilar o programa, considerando que a imagem foi feita para i386. As opções são:
  8. Rodar o programa no QEMU:

    Devemos tornar o executável disponível no ambiente do QEMU.


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.