Antes de fazer o teste, para não ter problemas com a quota ou de desempenho, configure o diretório CCACHE utilizando o comando:
$ export CCACHE_DIR="/tmp/.ccache"
$ cp /home/staff/islene/public_html/mc504-linux-compilado.tar.xz .
$ tar xJpvf mc504-linux-compilado.tar.xzAtenção: a opção p é muito importante para preservar as marcas de tempo e evitar as recompilações. Surgirá um diretório contendo a versão 3.17.2 do kernel Linux compilada com o arquivo de configuração config-3.17.2 e uma imagem mc504.img que foi criada por Glauber de Oliveira Costa para a turma do 1s2008 de sistemas operacionais.
qemu-system-i386 -hda mc504.img -kernel linux-3.17.2/arch/i386/boot/bzImage -append "ro root=/dev/hda"
usuário: root senha: rootProblemas com o teclado no ambiente do QEMU? Tente o seguinte:
Devemos mover o diretório ofd para linux-3.17.2/drivers e alterar o Makefile do diretório drivers acrescentando a linha
obj-y += ofd/A seguir, você deverá deverá executar make no diretório linux-3.17.2 que é a raiz dos fontes do kernel.
$ make -j 5 ARCH=i386
Precisaremos incluir os arquivos .ko no ambiente do QEMU. Para isso, criaremos um novo sistema de arquivos ext2 com os seguintes comandos:
$ dd if=/dev/zero of=drivers.img bs=4k count=20 $ mkfs.ext2 drivers.imgDepois, vamos copiar os arquivos .ko na imagem drivers.img com o debugfs.
$ debugfs -w drivers.img debugfs: write linux-3.17.2/drivers/ofd/ofd.ko ofd.ko debugfs: write linux-3.17.2/drivers/ofd/ofcd.ko ofcd.ko debugfs: write linux-3.17.2/drivers/ofd/ofcd-null.ko ofcd-null.koNo próximo teste com o QEMU, teremos de acrescentar esta imagem como um novo disco:
qemu-system-i386 -hda mc504.img -kernel linux-3.14.4/arch/i386/boot/bzImage -append "ro root=/dev/hda" -hdb drivers.imgNo QEMU, a imagem drivers.img deverá ser montada com o seguinte comando:
$ mkdir drivers $ mount -t ext2 /dev/hdb drivers/
$ insmod drivers/ofd.ko $ lsmod ... $ rmmod drivers/ofd.ko $ dmesg | grep ofd
$ insmod drivers/ofcd.ko $ lsmod ... $ dmesg | tail $ cat /proc/devices ... 252 ofcdÉ possível criar as entradas em /dev explicitamente:
$ mknod /dev/ofcd0 c 252 0 $ mknod /dev/ofcd1 c 252 1 $ mknod /dev/ofcd2 c 252 2 $ ls /devNo entanto, ainda não conseguimos utilizar estes arquivos.
$ cat /dev/ofcd0
$ insmod drivers/ofcd-null.ko $ ls /dev/ $ cat /dev/ofcd-null $ echo "teste" > /dev/ofcd-null
static char c; static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: read()\n"); buf[0] = c; return 1; } static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: write()\n"); c = buf[len - 1]; return len; }Esta abordagem está codificada no arquivo ofcd-lastchar-bug.c. Você pode testar com as aplicações teste-lastchar e teste-lastchar-invalid-buffer.
static char c; static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: read()\n"); if (copy_to_user(buf, &c, 1) != 0) return -EFAULT; else return 1; } static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off) { printk(KERN_INFO "Driver: write()\n"); if (copy_from_user(&c, buf + len - 1, 1) != 0) return -EFAULT; else return len; }Refaça os testes teste-lastchar e teste-lastchar-invalid-buffer com o driver ofcd-lastchar.
Se você procurar a documentação sobre copy_to_user e copy_from_user verá que estas funções podem dormir. Por quê?
Sugestão: tente implementar uma versão deste driver que armazene a última escrita com kmalloc e kfree.
./query_app to display the driver variables ./query_app -c to clear the driver variables ./query_app -g to display the driver variables ./query_app -s to set the driver variablesVocê deve rodar este exemplo e entender o funcionamento de ioctl. Como posso alterar o tipo de argumento passado para ioctl? Esta função permite grande flexibilidade?
No capítulo 4 do Kernel Hacking: ioctls: Not writing a new system call podemos encontrar a seguinte informação:
A system call generally looks like this asmlinkage long sys_mycall(int arg) { return 0; } First, in most cases you don't want to create a new system call. You create a character device and implement an appropriate ioctl for it. This is much more flexible than system calls, doesn't have to be entered in every architecture's include/asm/unistd.h and arch/kernel/entry.S file, and is much more likely to be accepted by Linus.No entanto, nem todos amam este design. Você consegue dizer algumas desvantagens?