Materials for Advanced x86

Course

old lessons :

Bibliography and References

Assignments

The git repository used for the assignments are on git-stos.lse.epita.fr

Exercises for the Tue May 19

Every exercises must have a Makefile, and the source code. It should contains tests.

Exercise 1 : string

Assignment : Implement a dynamic library with string functions in x86_64 assembly.

Your library should be usable with the following header :

#ifndef STRING_H
#define STRING_H

#include <stddef.h>

size_t strlen(const char *s);
char *strcpy(char *dest, const char *src);
void *memcpy(void *dest, const void *src, size_t n);

#endif

You should produce a library named libstring.so

Exercise 2 : cat

Assignment : Implement a cat binary in x86_64 assembly.

  • You binary must be PIE
  • without any external dependancies
  • you can still use the linux headers
  • you must use the syscall instruction for syscalls.

Example :

$ gcc -shared -nostartfiles -fno-builtin -nostdlib -o cat cat.S
$ IFS=:
$ for i in $PATH ; do sudo rm $i/cat ; done
$ echo foo > foo
$ ./cat foo
foo
$ echo foo | ./cat
foo
$ rm -f bar
$ ./cat bar
cat: Error
$
Exercise 3 : mptables

Assignment : Implement a stos kernel module that dumps the content of the mptables

  • This is a test module
  • It will output the content of the mptables with klog()

Project : MyKVM

Usage :

mykvm -f stos.boot
mykvm --help
mykvm -m 128 --kernel kernel/stos \
	--initrd initramfs.img \
	--modules module.ko,module2.ko \
	init.mode=all

other modes must be described in --help

Assignment : Create a small vm tool with kvm. The goal is to be able to boot stos.

stos.boot is a simple .ini file that looks like this (you will probably have to change the paths to match have something that make sense on your machine):

commandline=init.mode=all
kernel=/kernel/stos
initramfs=/kernel/initramfs.img
module=/kernel/modules/8259A.ko
module=/kernel/modules/cpuvar.ko
module=/kernel/modules/i8042.ko
module=/kernel/modules/i8254.ko
module=/kernel/modules/ide.ko
module=/kernel/modules/interrupts.ko
module=/kernel/modules/isa-serial.ko
module=/kernel/modules/pagination.ko
module=/kernel/modules/pci.ko
module=/kernel/modules/pm.ko
module=/kernel/modules/zero.ko
module=/kernel/modules/null.ko
module=/kernel/modules/kmsg.ko
module=/kernel/modules/16550.ko
module=/kernel/modules/pci-serial.ko
module=/kernel/modules/devfs.ko
module=/kernel/modules/ext2.ko
module=/kernel/modules/mbr_part_table.ko
module=/kernel/modules/mbrfs.ko
module=/kernel/modules/ramfs.ko
module=/kernel/modules/vfs.ko
module=/kernel/modules/bin_elf.ko
module=/kernel/modules/block.ko
module=/kernel/modules/char.ko
module=/kernel/modules/commandline.ko
module=/kernel/modules/fifo_io_sched.ko
module=/kernel/modules/fifo_scheduler.ko
module=/kernel/modules/first_fit_kmalloc.ko
module=/kernel/modules/frame_allocator.ko
module=/kernel/modules/libraries.ko
module=/kernel/modules/posix.ko
module=/kernel/modules/start_uland.ko
module=/kernel/modules/test.ko
module=/kernel/modules/syscall.ko
module=/kernel/modules/syslog.ko
module=/kernel/modules/task.ko
module=/kernel/modules/init.ko

Steps :

  • Create basic VM
  • Boot some code directly in PM mode
  • Add serial handling
  • add pagination like in stos.grub
  • start to handle stos boot protocol
  • start building from that :
    • module support
    • memory map support
    • commandline support
    • initramfs support
    • more devices

Please note that the absolute minimum is to be able to boot the stos core, with commandline support, complete memory mapping.

Module and initramfs support are the 2nd step.

For debugging support, and to be able to see if the code behave correctly in qemu and in your code, you can implement a subset of the multiboot spec with :

  • 32bit
  • multiboot
  • serial

More explanation (in French)

Voici quelques précisions sur le sujet et la marche à suivre (une update du site arrivera aussi, plus tard, histoire de refléter ces changements)

  • Donnez moi un README m’expliquant comment faire marcher votre projet exactement, avec les fichiers de conf, comment compiler la version de stos que vous avez utilisé, etc…
  • Il est a noter que je retirerai des points à tout ceux qui incluent directement stos dans leur dépots. Je préfère voir un script/submodule/whatever plutôt que ça (à préciser dans le README)
  • La partie obligatoire (comprendre, pour avoir 10 si ca marche) est :
    • chargement du core
    • pagination
    • gestion du protocole de boot de stos
    • commandline
    • serial en output
  • Les étapes suivantes sont :
    • modules
    • initramfs
  • En bonus potentiels :
    • tests pour valider le tout (dans stos, ou en userland)
    • gestion complète du serial (input, output, irq)
    • vga text
    • supprimer ioctl(CREATE_IRQCHIP)
  • le multiboot est ici indiqué pour vous aider à debugger plus facilement, vu que vous pourrez lancer des exemples qui tournerons dans qemu et dans votre vm. Cela ne vaut aucun points si vous n’avez pas la partie mandatory.

  • Faites attention aux headers de stos, ils sont valide uniquement en 32bit, comme votre binaire sera 64bit, il faut patcher les structures pour être aligné correctement (Attention à la règle de padding de gcc sur les valeurs 64bit).

  • Il y a une erreur dans les slides par rapport à l’ioctl KVM_SET_IDENTITY_MAP_ADDR. En effet, la définition de l’ioctl est :

    #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64) et non #define KVM_SET_IDENTITY_MAP_ADDR _IO(KVMIO, 0x48) je vous laisse en déduire ce qu’il fallait marquer.

  • Pour la pagination, il y a un petit détail que je ne vous ai pas précisé. KVM ne sait pas démarrer directement avec %cr0.PG = 1, il faut donc faire un trampoline pour activer la pagination avant de lancer stos.