Monday, March 7, 2016

Adding a User Program to xv6

It is pretty much simple and straightforward to write a user level C program for xv6 and making it available for the user at the shell prompt. When we go forward and implement much advanced things on the xv6 OS, most of the times we need to test those features by using a user level program. Therefore, knowing how to write such programs and adding it into the xv6 source code for compilation is a necessary thing. Therefore, I decided to write down those simple steps even though it is very simple.

First of all, let's create a C program like the following. We save it inside the source code directory of xv6 operating system with the name asankas_program.c or whatever the name you prefer.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// A simple program which just prints something on screen

#include "types.h"
#include "stat.h"
#include "user.h"

int
main(void)
{
 printf(1, "Asanka's first user program on xv6\n");
 exit();
}


Now, we have to edit the Makefile of the xv6 source code in order to let the compiler know that we have a program like this and we need it to be compiled with other system programs. In the Makefile, there are two places in which we need to put entries.

Find the place with some lines like the following. We have to add a line as shown below to notify about our new program.

UPROGS=\
    _cat\
    _echo\
    _forktest\
    _grep\
    _init\
    _kill\
    _ln\
    _ls\
    _mkdir\
    _rm\
    _sh\
    _stressfs\
    _usertests\
    _wc\
    _zombie\
    _asankas_program\


Similarly, find the place with the lines like below. Add an entry as shown to indicate that we have a program called asankas_program.c there.

EXTRA=\
    mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c kill.c\
    ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c\
    asankas_program.c\
    printf.c umalloc.c\
    README dot-bochsrc *.pl toc.* runoff runoff1 runoff.list\
    .gdbinit.tmpl gdbutil\


Now, our Makefile and our user program is ready to be tested. Enter the following commands to compile the whole system.

make clean
make


Now, start xv6 system on QEMU and when it booted up, run ls command to check whether our program is available for the user. If yes, give the name of that executable program, which is in my case is asankas_program to see the program output on the terminal. The figure above shows this output on the QEMU emulator window.

9 comments:

  1. thank you very much ... enjoy fetch decode execution ;D

    ReplyDelete
  2. Thank you! Nicely explained.

    ReplyDelete
  3. it is saying

    ld: warning: cannot find entry symbol main; defaulting to 0000000000000000
    objdump -S _program\ > program\.asm
    objdump: '_program ': No such file
    make: *** [_program\] Error 1


    please check

    ReplyDelete
    Replies
    1. The name you put in uprogs the same that the name you put on extra. Like example and example.c?

      Delete
  4. Why the header files are a bit different from a regular c program (for example stdio.h)?

    ReplyDelete
    Replies
    1. stdio.h is a standard C library header file. xv6 OS does not include the standard C library. It has its own library functions which we include in user programs.

      Delete
  5. I follow your instruction, but didn't work. I got the following errors.
    syscall.o:(.rodata+0x58): undefined reference to `sys_procstate'
    Makefile:117: recipe for target 'kernel' failed
    make: *** [kernel] Error 1

    ReplyDelete
  6. if i have a progam that uses , and many such header files that give error in xv6, how can I add them to the user program?

    ReplyDelete