# Xv6 introduction - STSD
In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching...
Author: Pengzhan Hao

Xv6 introduction | STSD

# Xv6 introduction

In this post, you will learn a few basic concepts of xv6. Learning path will be closed coupled to first project assignment I gave when I assisted in teaching OS classes. Understand system call and know how to implement a simple one will be coved as the first half. In the second half of this post, I will discuss a little bit more on how to debug xv6 using gdb.

## Xv6 Systemcall

To invoke a system call, we have to first define a user mode function to be the interface of the kernel instruction in file user.h.

    void function (void);

This interface-like function will then pass the function name, in this case function, to usys.S. When using user mode function in programs, usys.S will generate a reference to SYS_function and push system call number of this function into %eax. After that, system can know from syscall.c and determining whether this system call is available. We must define same name system function and add it into syscall.h and syscall.c.

    #define SYS_function ##  // ## is the system call number
    [SYS_function]  sys_function // real system function name
    extern int sys_function(void); // real system function declaration

After adding these sentences to syscall files, we can implement real function in specific place where you want to make the function works well.

Sometimes, we need to pass variables among system calls. In this case, variables’ values are not necessary and even can’t be pass directly into system_function. When invoke a system call function, all variables of this system call will be pushed into current process’ stack. In file syscall.c, multiple functions are provided to get these variables from the process. I won’t waste time on explaining how to use these functions especially when elegant and detailed comments were written in source codes. However, I will explain concepts and how process organized and works in xv6 in future articles.

## Debug xv6 with gdb

Please make sure that you have used gdb before. If you never used gdb, you may write a simple 50-100 lines c code and practice how to use gdb first.

- GDB Manual
- GDB cheatsheet (pdf)

To make sure xv6 gdb enabled, please check if .gdbinit.tmpl file exist. This file is used for generate .gdbinit file which you can late consider it as a configuration for gdb.

Before running the xv6 instance in QEMU, one more thing you need to know is that using gdb to debug xv6 must be attached remotely. This is because xv6 was running within QEMU, and emulator is virtually gapped from the host device. Later when you start debugging, QEMU will open a gdb server to let gdb client connect to.

Once you want to start, using following command to compile and run xv6

    $ make qemu-nox-gdb
    *** Now run 'gdb'.
    qemu-system-i386 -nographic -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp 2 7

At this moment, it feels xv6 was stuck, this is because QEMU is ready to be connected by the gdb client. You may use the .gdbinit to automatically finish this remote connection by simple typein following command in another terminal.

    $ gdb -x .gdbinit
    GNU gdb (Debian 8.2.1-2+b3) 8.2.1

    ...

    The target architecture is assumed to be i8086
    [f000:fff0]    0xffff0: ljmp   $0x3630,$0xf000e05b
    0x0000fff0 in ?? ()
    + symbol-file kernel
    warning: A handler for the OS ABI "GNU/Linux" is not built into this configuration
    of GDB.  Attempting to continue with the default i8086 settings.

    (gdb)

Now within this gdb client shell, type ‘c’ to continue the xv6, and you will see xv6 start execution in the first terminal.

At this moment, you may add breakpoints to your code to see if your code is correctly implemented or not.

One more thing, if you open .gdbinit file, you’ll find that it by default connect to a localhost target. If you are working on some other environment that target and client were not placed in the same device, change the localhost to ip address correspondingly. Using ssh may connect to different physical devices under same domain name, this is because load balancer were used. To check ip address, search command ip.

    target remote localhost:28467
    # target remote [ip-addr]:28467

PREVIOUS Some of my previews experiment works: 2016
NEXT Generate Word Cloud Figures with Chinese-Tokenization and WordCloud python libraries
Search