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 3.17.2

Atenção: como estes arquivos são muito grandes, deveremos fazer nossos testes no /tmp das máquinas do laboratório.
  1. Precisaremos do arquivo mc504-linux.tar.xz. Se estivermos na rede do IC-03 podemos executar o seguinte comando:
    $  cp /home/staff/islene/public_html/mc504-linux.tar.xz .
    
  2. Após obtermos o arquivo, devemos executar:
    $ tar xJvf mc504-linux.tar.xz
    
    Surgirá um diretório contendo a versão 3.17.2 do kernel Linux contendo um arquivo .config adequado para o experimento. Alé disso, iremos trabalhar com a imagem mc504.img que foi criada por Glauber de Oliveira Costa para a turma do 1s2008 de sistemas operacionais.

  3. Compile o kernel com
    $ cd linux-3.17.2
    $ make -j 5 ARCH=i386    
      
    Para não ter problemas com a quota, configure previamente o diretório CCACHE utilizando o comando:
    $ export CCACHE_DIR="/tmp/.ccache"
    
  4. Teste o kernel com a imagem utilizando o QEMU:
    $  qemu-system-i386 -hda mc504.img -kernel linux-3.17.2/arch/i386/boot/bzImage -append "ro root=/dev/hda" 
    

  5. 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-3.17.2/arch/x86/syscalls/syscall_32.tbl, acrescentando uma nova linha ao final do arquivo:
      357     i386    mycall                  sys_mycall
    
  2. Incluir uma declaração da função sys_mycall em um ponto adequado do arquivo linux-3.17.2/include/linux/syscalls.h
    asmlinkage long sys_mycall(void);
    
  3. Incluir o código para função no diretório linux-3.17.2/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-3.17.2/arch/x86/kernel/, incluindo uma linha:
    obj-y                                   += mycall.o
    
  5. No diretório linux-3.17.2 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(357); 
      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 um parâmetro inteiro (key) e o armazene no espaço de kernel. Crie um par de chamadas de sistema getkey e setkey para armazerar e recuperar esta chave. Você precisará fazer também uma programa em C para testar a sua nova chamada 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

Esta tarefa não é um dos projetos principais da disciplina. Os grupos que entregarem o código da chamada de sistema, com um arquivo README justificando o uso das funções citadas acima via Moodle poderão ganhar até um ponto na média das notas de projeto.