Instituto de Computação - UNICAMP

MC504/MC514 - Sistemas Operacionais

Implementação de Chamadas de Sistema

Islene Calciolari Garcia

Dicas

Veja algumas dicas aqui.

Importante: No laboratório, USE O TMP!

Atenção: como o espaço em disco utilizado durante este experimento é muito grande, caso os testes sejam feitos no laboratório deveremos utilizar o diretório /tmp das máquinas.
  $ mkdir /tmp/raXYZXYZ
  $ cd /tmp/raXYZXYZ

Assim, você não esgota a sua quota e não prejudica o desempenho da rede para os outros. Pelos mesmos motivos, antes da compilação do kernel, configure o diretório CCACHE utilizando o comando:

$ export CCACHE_DIR="/tmp/.ccache"

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.8.6

  1. Obtenha a versão 4.8.6 ou outra verão recente do kernel em kernel.org. Execute a descompactação com o comando:
    $ pwd
    /tmp/raXYZXYX
    $ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.8.6.tar.xz
    $ tar xJvf linux-4.8.6.tar.xz 
    
  2. Obtenha a imagem ArchLinux_mc504.cow que foi criada por Tiago Gimenes no 1s2016. Esta imagem contém o gcc e é um pouco maior e mais completa do que a imagem utilizada em semestres anteriores.

  3. Obtenha o arquivo de configuração config-4.8.6 adequeado para rodar com o QEMU.

  4. Instale o arquivo de configuração e compile o kernel.
    $ cd linux-4.5.8
    $ cp ../config-4.5.8 .config
    $ make -j 5 ARCH=i386    
      
  5. Teste o kernel com a imagem utilizando o QEMU:
    $  qemu-system-i386 -hda ArchLinux_mc504.cow -kernel linux-4.8.6/arch/i386/boot/bzImage -append "rw root=/dev/hda" 
    

  6. Quando o sistema entrar poderemos fazer login com usuário root, sem senha.

  7. Para sair sem corromper a imagem:
    $ poweroff
        

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.8.6/arch/x86/entry/syscalls/syscall_32.tbl, acrescentando uma nova linha ao final do arquivo:
      380     i386    mycall                  sys_mycall
    
  2. Incluir uma declaração da função sys_mycall em um ponto adequado do arquivo linux-4.8.6/include/linux/syscalls.h
    asmlinkage long sys_mycall(void);
    
  3. Incluir o código para função no diretório linux-4.8.6/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.8.6/arch/x86/kernel/, incluindo uma linha:
    obj-y                                   += mycall.o
    
  5. No diretório linux-4.8.6 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(380); 
      printf("Retorno da chamada de sistema: %d.\n", r);
      return r;
    }
    
  7. Devemos tornar este código visível para o QEMU. Uma opção simples é exportar o arquivo que contém o código como um disco:
    $ qemu-system-i386 -hda ArchLinux_mc504.cow -kernel linux-4.8.6/arch/i386/boot/bzImage -append "rw root=/dev/hda" -drive format=raw,file=ex-mycall.c
    

    Após logar no sistema, devemos executar os comandos abaixo. O gcc irá ignorar os caracteres nulos adicionados no processo.

    $ cat /dev/hdb > ex-mycall.c
    $ gcc ex-mycall.c -o ex-mycall
    $ ./ex-mycall
    
  8. Outra opção é criar um mini sistema de arquivos. O debugfs será utilizado porque não temos permissão de root nas máquinas do laboratório.
    $ dd if=/dev/zero of=ext2.dmp bs=1k count=100
    $ mkfs.ext2 ext2.dmp
    $ debugfs -w ext2.dmp
      debugfs: write ex-mycall.c ex-mycall.c
      debugfs: quit
    $ qemu-system-i386 -hda ArchLinux_mc504.img -kernel linux-4.8.6/arch/i386/boot/bzImage -append "rw root=/dev/hda" -drive format=raw,file=ext2.dmp
    

    Após logar no sistema, devemos executar:

    $ mkdir mnt
    $ mount -t ext2 /dev/hdb mnt
    $ cd mnt
    $ gcc ex-mycall.c -o ex-mycall
    $ ./ex-mycall
    

Projeto 2: Chaves temporárias

Você deverá implementar uma chamada de sistema que receba pares de chave/valor com tempo de vida determinado no momento da criação. A chave deve ser um parâmetro inteiro e o valor uma cadeia de caracteres. Crie as chamadas de sistema gettmpkey e settmpkey para armazerar e recuperar estes pares de chave/valor. Você precisará fazer também um programa em C para testar as suas novas chamadas de sistema.

Entrega: 14 de dezembro via Moodle. Apresentação obrigatória no lab por pelo menos um membro do grupo.