Wednesday, March 26, 2014

[OSDI] Adding a New System Call in Linux Kernel

Steps

  1. modify arch/x86/kernel/syscall_table_32.S
  2. modify arch/x86/include/asm/unistd_32.h
  3. modify arch/x86/include/asm/syscalls.h
  4. modify arch/x86/kernel/Makefile
  5. add and implement arch/x86/kernel/hello.c
  6. make && sudo make modules_install && sudo make install && sudo reboot (Compile Kernel)

modify arch/x86/kernel/syscall_table_32.S

this file contains all the syscall names, so add a new line for our new system call at the end of the file
add .long sys_mycall at the end

modify arch/x86/include/asm/unistd_32.h

add #define __NR_mycall 338 before #ifdef __KERNEL__
modify #define NR_syscalls <number of system calls + 1>

modify arch/x86/include/asm/syscalls.h

the interface (declaration) of the system calls
add asm_linkage int mycall(void); after asmlinkage long sys_mmap(...);

modify arch/x86/kernel/Makefile

make sure the new system call will be compiled
add obj-y += mycall.o after obj-y := process...

add and implement arch/x86/kernel/hello.c

#include <linux/kernel.h>
#include <linux/linkage.h>
asmlinkage int sys_mycall(void) {
    printk("Hello, how are you?\n");
    return 0;
}

Test

  • modify /usr/include/asm/unistd_32.h
  • modify /usr/include/bits/syscall.h
  • write a program to test it
  • see the output in dmesg
modify /usr/include/asm/unistd_32.h
add #define __NR_mycall 341 at the end, before #endif
modify /usr/include/bits/syscall.h
add #define SYS_mycall __NR_mycall at the end of the file
write a program to test it

#include <syscall.h>#include <stdio.h>
int main() {
    int r;
    r = syscall(__NR_mycall);
    printf("return value = %d\n", r);
    return 0;
}

see the output in dmesg
simply type "dmesg" to check if the output is there

Reference

Tuesday, March 25, 2014

[OSDI] Compile Kernel (Commands)

Compile Kernel

  • cp ./.config ./.config.bk
  • cp /boot/config-<tab> ./.config
  • make menuconfig
  • make ###compiling to create a compressed kernel image
  • make modules ###compiling to kernel modules
  • sudo make modules_install ###install kernel modules
  • sudo make install ###install kernel itself

Reference

Monday, March 24, 2014

Add a New User with Home and in Sudoer

Ha, I can't memorise this one, so I am taking the note here.
  • sudo useradd -d /home/heron -m heron
  • sudo passwd heron
  • sudo adduser heron sudo
    • (Fedora) gpasswd wheel -a heron
    • (Fedora) visudo -> remove '#' in front of %wheel

Thursday, March 20, 2014

TODO and FIXME List in VIM

Programmers like to leave "TODO" or "FIXME" in comments to remind themselves that there's something unfinished or unsolved. It's not only important for reminding, but also a good way to tell notify the other co-workers: "there's something we need to fix", which is a better way instead of email/IMs.

To setup the "TODO" and "FIXME" list in VIM is slightly simple, just add the following line in ~/.vimrc:
command Todo noautocmd vimgrep /TODO\|FIXME/j ** | cw
Type ":Todo" in VIM to obtain the list in VIM.



Reference

GNU Split Screen

Notes for split screen commands

  • ctrl+a shift+\ : create new vertically split window
  • ctrl+a shift+s : create new horizontally split window
  • ctrl+a Tab : move cursor to the other window
  • ctrl+a shift+x : close current window

*Enable vertical split on Mac: http://old.evanmeagher.net/2010/12/patching-screen-with-vertical-split-in-os
* Meet bug ("pty.c:38:26: fatal error: sys/stropts.h: No such file or directory") on Fedora: http://savannah.gnu.org/bugs/?36693

Tuesday, March 18, 2014

[OSDI] Ways for Protecting Shared Data/Process Problems


Ways for protecting shared data/process problems
  1. atomic operation: http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/Atomic_Operations.htm
    • apply a single variable as a lock, check it before entering critical session
  2. disable interrupt: http://stackoverflow.com/questions/3427546/what-is-meant-by-disabling-interrupts
    • sometimes it's not necessary
    • costs a lot
  3. interrupt mask
    • device drive interrupt handler
  4. program reentry
  5. disable kernel preemption
  6. spin lock
    • implemented by atomic operation
    • run for loop while it's locked

Wednesday, March 12, 2014

Create New Git Repo

Yep, this should be basic, but I always can't memorise the commands. Here, I am writing them down.

p.s. let's use git@heron.nctucs.net:~/heron-web.git for example.

On Git Server Side

  • mkdir heron-web.git
  • cd heron-web.git/
  • git init --bare

In My Local Code Directory

  • cd <path-to-the-code>
  • git init
  • vim .gitignore
  • git add -A
  • git commit -a -m "init commit"
  • git remote add original git@heron.nctucs.net:~/heron-web.git
  • git push -u original master

Clone in Other Place

  • git clone git@heron.nctucs.net:~/heron-web.git
  • cd heron-web

[OSDI] Modifying bootsect.s on Linux v0.11 for Multi Booting Support

In Linux v0.11, the code for booting is written in X86 Assembly Code. It took me a little while understand the code and put some modification on it for the OSDI assignment.

In the assignment, we have to add a new bootable section in the floppy disk, and boot into that section. This part is described in the assignment document. Then, we have to enable the user to select which section he/she wants to boot, linux v0.11 or our new section (hello.s).

First we print out our custom message by calling "int $0x10", then read the insert key by calling "int $0x16". And, by looking up ASCII table, we check if the inserted code is '1' or '2' to boot the corresponding section.

Write "hello binary image" into Floppy Second Section

Modified tools/build.sh as below, so that we get our hello.s into the second section.
#!/bin/bash
# build.sh -- a shell version of build.c for the new bootsect.s & setup.s
# author: falcon <wuzhangjin@gmail.com>
# update: 2008-10-10

bootsect=$1
setup=$2
system=$3
IMAGE=$4
hello_img=$5    # [OSDI lab2]
root_dev=$6

# Set the biggest sys_size
# Changes from 0x20000 to 0x30000 by tigercn to avoid oversized code.
SYS_SIZE=$((0x3000*16))

# set the default "device" file for root image file
if [ -z "$root_dev" ]; then
        DEFAULT_MAJOR_ROOT=3
        DEFAULT_MINOR_ROOT=1
else
        DEFAULT_MAJOR_ROOT=${root_dev:0:2}
        DEFAULT_MINOR_ROOT=${root_dev:2:3}
fi

# Write bootsect (512 bytes, one sector) to stdout
[ ! -f "$bootsect" ] && echo "there is no bootsect binary file there" && exit -1
dd if=$bootsect bs=512 count=1 of=$IMAGE 2>&1 >/dev/null

# [OSDI lab2] add custom hello program
[ ! -f "$hello_img" ] && echo "there is no hello binary file there" && exit -1
dd if=$hello_img seek=1 bs=512 count=1 of=$IMAGE 2>&1 >/dev/null

# Write setup(4 * 512bytes, four sectors) to stdout
[ ! -f "$setup" ] && echo "there is no setup binary file there" && exit -1
dd if=$setup seek=2 bs=512 count=4 of=$IMAGE 2>&1 >/dev/null

# Write system(< SYS_SIZE) to stdout
[ ! -f "$system" ] && echo "there is no system binary file there" && exit -1
system_size=`wc -c $system |cut -d" " -f1`
[ $system_size -gt $SYS_SIZE ] && echo "the system binary is too big" && exit -1
dd if=$system seek=6 bs=512 count=$((2888-1-4)) of=$IMAGE 2>&1 >/dev/null

# Set "device" for the root image file
echo -ne "\x$DEFAULT_MINOR_ROOT\x$DEFAULT_MAJOR_ROOT" | dd ibs=1 obs=1 count=2 seek=508 of=$IMAGE conv=notrunc  2>&1 >/dev/null

Put Custom "hello.s" Section into the Directory

Yes, put "hello.s" under boot/. However, the hello.s I am using is not my work but the TA's, so it may not a good idea to put the code here.

Modify Makefile

Add the following things in boot/Makefile:
hello: hello.s
    @$(AS) -o hello.o hello.s
    @$(LD) $(LDFLAGS) -o hello hello.o
    @objcopy -R .pdr -R .comment -R.note -S -O binary hello

And, add the following things in ./Makefile:
Image: boot/bootsect boot/setup tools/system boot/hello
    @cp -f tools/system system.tmp
    @strip system.tmp
    @objcopy -O binary -R .note -R .comment system.tmp tools/kernel

    @tools/build.sh boot/bootsect boot/setup tools/kernel Image boot/hello $(ROOT_DEV)
    @rm system.tmp
    @rm tools/kernel -f
    @sync
boot/hello: boot/hello.s
    @make hello -C boot

Modify bootsect.s

And, here's the code I added in boot/bootsect.s:

# [OSDI lab2]: booting selection here
# print some message first
    mov     $0x03, %ah              # read cursor pos
    xor     %bh, %bh
    int     $0x10
    mov     $24, %cx
    mov     $0x0007, %bx            # page 0, attribute 7 (normal)
    mov     $msg2, %bp
    mov     $0x1301, %ax            # write string, move cursor
    int     $0x10
read_key:
    mov $0x0000, %ax
    int $0x16
    cmp $0x31, %al
    je load_setup
    cmp $0x32, %al
    je load_hello
    jmp read_key
# you can implement the load hello image code at here
load_hello:
    mov     $0x0000, %dx            # drive 0, head 0
    mov     $0x0002, %cx            # setup now change to sector 3, track 0 [OSDI lab2] editted
    mov     $0x0200, %bx            # address = 512, in INITSEG
    mov $0x0201, %ax                # service 2, nr of sectors
    int     $0x13                       # read it
    jnc     ok_load_hello           # ok - continue
    mov     $0x0000, %dx
    mov     $0x0000, %ax            # reset the diskette
    int     $0x13
    jmp     load_hello
ok_load_hello:
# Get disk drive parameters, specifically nr of sectors/track
    mov     $0x00, %dl
    mov     $0x0800, %ax            # AH=8 is get drive parameters
    int     $0x13
    mov     $0x00, %ch
    mov     %cx, %cs:sectors+0      # %cs means sectors is in %cs, [H]: not understanding
    mov     $SYSSEG, %ax
    mov     %ax, %es                # segment of 0x010000
    call    read_it
    call    kill_motor
# load the setup-sectors directly after the bootblock.
# Note that 'es' is already set up.
load_setup:

    ...

Reference

* thanks Schwannden Kuo for correcting my English