Giter VIP home page Giter VIP logo

opsys-lab6's Introduction

Lab 6 - Linux kernel drivers

Table of Contents

3.4 Tasks
3.4 Questions
3.9 Questions
4.2 Tasks
4.3 Questions

Part 1: Loadable kernel module

#### 3.3 Tasks

alt text

#### 3.4 Questions
  1. The makefile has a variable which specifies the kernel directory: KDIR := /lib/modules/$(shell uname -r)/build. On the virtual image, this variabla becomes /lib/modules/2.6.27.7-smp/build.
  2. Kernel modules do not have access to standard C libraries. We have to use libraries provided by the kernel. printk() is a function defined in the kernel which is almost eqvuivalent to printf().
  3. The -C flag in the makefile tells make to change to the specified directory before doing anything else. I navigated to /lib/modules/2.6.27.7-smp/build and discovered another Makefile, which performs the actual build. I scrolled through the file and noticed some code which handles both modules and clean. I didn't quite understand what the -M flag is doing though. I wasn't able to find it in the man pages either.
  4. If we remove MODULE_LICENSE from our code, the kernel will complain when we are loading the module: modpost: missing MODULE_LICENSE().

3.7 Questions

a) & c)

package main

import "os"
import "fmt"
import "log"

func main() {
	file, err := os.Open("/dev/simp_read")
	if err != nil {
		log.Fatal(err)
	}
	data := make([]byte, 100)
	count, err := file.Read(data)
	if err != nil {
		log.Fatal(err)
	}
	//The minus 1 is to get rid of the trailing \n
	fmt.Printf("%q\n", data[:(count-1)])
}

b)

static bool msgWritten;
// open function - called when the "file" /dev/simp_read is opened in userspace
static int dev_open (struct inode *inode, struct file *file) 
{
	counter++;
	printk("simplkm_read: skeleton device driver open\n");
	return 0;
}
// read function called when from /dev/simp_read is read
static ssize_t dev_read (struct file *file, char *buf, size_t count, loff_t *ppos) 
{
	if (msgWritten) {
		return 0;
	}

	msgWritten = true;
	
	char theBuf[50];
	int bufLen=0;

	sprintf(theBuf, "Number of driver read=%d\n", counter );
	bufLen = strlen( theBuf);
	
	printk("simplkm_read: %s, buflen=%d\n",theBuf, bufLen );
		
	if( copy_to_user( buf, theBuf,  bufLen ) )
	{
		printk("simplkm_read: copy_to_user failed\n" );
		return -EFAULT;
	}
	else
		return bufLen;
}

Extend the driver with write()

#### 3.9 Questions

a)

static ssize_t dev_write (struct file *file, const char *buf, size_t count, loff_t *ppos)
{
	sprintf(msg, "");
	int bufLen=0;

	if( copy_from_user( msg, buf, count ) )
	{
		printk("simplkm_rw: copy_from_user failed\n");
		return -EFAULT;
	}
	else
	{
		printk(KERN_INFO "%s\n", msg);
		sprintf(msg + strlen(msg), "\n");
		bufLen = strlen( msg );
		return bufLen;
	}
}

And add this line to the file_operations struct:

.write = dev_write

c)

package main

import (
	"flag"
	"fmt"
	"log"
	"os"
)

func main() {
	msg := flag.String("write", "", "message to write to /dev/simp_rw")
	flag.Parse()

	if *msg != "" {
		write(*msg)
	} else {
		read()
	}
}

func write(msg string) {
	file, err := os.OpenFile("/dev/simp_rw", os.O_RDWR, 0644)
	defer file.Close()
	checkError(err)
	_, err = file.Write([]byte(msg))
	checkError(err)
}

func read() {
	file, err := os.Open("/dev/simp_rw")
	defer file.Close()
	checkError(err)
	data := make([]byte, 100)
	count, err := file.Read(data)
	checkError(err)
	fmt.Printf("%q\n", data[:(count-1)])
}

func checkError(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

d) I believe this question is more relevant for task b. Task a only handles one message, so we don't have to think about protection. The buffer is cleared every time write() is called, so we will never have a buffer overflow.

#### 4.2 Tasks 1. The kernel functions equivalent to ```malloc()``` and ```free()``` are ```kmalloc()``` and ```kfree()```. User space applications do not have access to physical memory addresses. We are trying to use an address from physical memory to access something in virtual memory, that is why we get a segmentation fault. I guess there is a small chance that we could actually get an address which points to something in both kernel and user space. 2. The kernel can access all memory, so in this case we have no problem reading what the poiner is pointing to. 3. Processes can not share memory. Each process runs in its own dedicated address space in virtual memory. 4. Two threads within the same process runs in the same address space. We can access global variables from multiple threads in the same process. 5. As I mentioned earlier, the kernel have access to all memory. That is why we don't get a segmentation fault in this case.

alt text

#### 4.3 Questions

a)

Where memory is allocated Tried to dereference Textual value of pointer Result
Kernel Userspace cd448180 Segmentation fault
Userspace Kernel 0x804a170 Successfully reads the data
Userspace process 1 Userspace process 2 0x804a008 Segmentation fault
Userspace thread 1 Userspace thread 2 0x804a008 Successfully reads the data
Kernel driver 1 Kernel driver 2 cd19e500 Successfully reads the data

b)

Why do we have to use copy_to_user() and copy_from_user() in a kernel driver? Protection is a keyword here. We should not be able to acecss kernel addresses directly from user space. The functions check this by calling access_ok() on the adress. The functions handles errors as well. This means that if we encounter a page fault during copy, we can return -EFAULT to the user and prevent the kernel from crashing.

opsys-lab6's People

Contributors

sandves avatar

Watchers

Hein Meling avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.