Instituto de Computação - UNICAMP

MC504 - Sistemas Operacionais

Implementação de Chamadas de Sistema

Islene Calciolari Garcia


Ambiente de testes

Siga as instruções para o uso do QEMU.

Testando uma 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.11.3/arch/x86/entry/syscalls/syscall_32.tbl, acrescentando uma nova linha ao final do arquivo:
      384     i386    mycall                  sys_mycall
    
  2. Incluir uma declaração da função sys_mycall em um ponto adequado do arquivo linux-4.11.3/include/linux/syscalls.h
    asmlinkage long sys_mycall(void);
    
  3. Incluir o código para função no diretório linux-4.11.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.11.3/arch/x86/kernel/, incluindo uma linha:
    obj-y                                   += mycall.o
    
  5. No diretório linux-4.11.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(384); 
      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.11.3/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.cow -kernel linux-4.11.3/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
    

Dicas

Veja outras dicas para implementação de system calls.