HW8: Cabinet

Skeleton code setup

You will be implementing a syscall, inspect_cabinet(), with syscall number 405.

In the skeleton code, we provide a patch that you should apply to your 4.4.50 kernel. Move ikea.patch into a fresh Linux 4.4.50 kernel source directory, and run the following command:

patch -p1 < ikea.patch

Build and install your kernel as you did before using mmk, and then run this command to install the uapi/ headers:

sudo make headers_install INSTALL_HDR_PATH=/usr

Now you should be able to #include <linux/cabinet.h> from userspace!

We’ve provided a tester program named cabinet_inspector inside of test/: Try compiling it to make sure your headers are installed. You may run cabinet_inspector as follows:

sudo ./cabinet_inspector [<vaddr> [<pid>]]

See “Tester” section below for usage details.

We’ve also provided a reference_cabinet.ko which you may insert to compare against your own code’s functionality.


For this assignment, you will be implementing the syscall in a module. Please write your code inside of the provided modules/cabinet.c file, and do not modify the provided boilerplate code. You should start your code in inspect_cabinet(), and feel free to define and call any more functions inside your module.

Once you have completed writing your code, you should test it with the given tester. In your README.txt, you should describe how you tested your code, what processes you tested it with, and what you found.

You will be submitting everything inside of the provided module/ directory, so you should copy those files into your submission directory and run git init in there. You should also be submitting a README.txt. For example, the following files should be tracked in your hw8 submission directory:

$ git ls-files

Note that for this assignment, you will not be submitting a sparse repo.


The function prototype for inspect_cabinet() is the following:

int inspect_cabinet(pid_t pid, unsigned long vaddr, struct cab_info *inventory);

inspect_cabinet() will take in three arguments:

inspect_cabinet() will report the following information about the process with that PID:

This information will be used to populate the struct cab_info, which is defined as follows:

struct cab_info {
    unsigned long paddr;        /* the physical address the virtual address is mapped to */
    unsigned long pf_paddr;     /* the physical address of its page */
    unsigned long pte_paddr;    /* the physical address of its PTE */
    unsigned long pmd_paddr;    /* the physical address of its PMD */
    unsigned long pud_paddr;    /* the physical address of its PUD */
    unsigned long pgd_paddr;    /* the physical address of its PGD */
    int modified;           /* 1 if modified, 0 otherwise */
    int refcount;           /* number of processes sharing the address */

The user calling the syscall must first allocate this struct in userspace, and provide the pointer to it as a parameter.

Return values and error handling


The usage for the tester is as follows (it must be run as root):

sudo ./cabinet_inspector [<vaddr> [<pid>]]

The tester will call cabinet_inspector() with the specified virtual address and PID, and print out the information returned.

Example output:

inspecting cabinet for <virtual address> of pid=<pid>
paddr: <physical address>
pf_paddr: <physical address>
pte_paddr: <physical address>
pmd_paddr: <physical address>
pud_paddr: <physical address>
pgd_paddr: <physical address>
modified: [yes|no]
refcount: <reference count>

You may use /proc/<pid>/maps to find useful virtual memory addresses to test this on.

You may also consult test/session{1,2,3}.txt for example shell sessions testing with the cabinet_inspector. The README.txt in test/ will contain more documentation about this.

Useful Resources

Below is some online reading material that you may find helpful for this assignment:


The Cabinet assignment and reference implementation are designed and implemented by the following TAs of COMS W4118 Operating Systems I, Spring 2017, Columbia University:

Last updated: 2017–04–23