Starting from:

$30

CSC3150 Assignment 5

CSC3150 Assignment 5
In Assignment 5, you are required to make a prime device in Linux, and implement file
operations in kernel module to control this device.
Outline:
 We will make a device under /dev by mknod command.
 This device can find n-th prime number.
 You will implement file operations in a kernel module to control this device.
 And implement ioctl function to change the device configuration.
 Simulate registers on device by allocating a memory region.
Global View:
Specification:
 Register character device and make it live:
 You can use alloc_chrdev_region() to allocate a range of char device numbers.
 And get available number by MAJOR() and MINOR() macro.
 In your kernel module, you could allocate a cdev structure by cdev_alloc() and
initialize it by cdev_init() to bind cdev file_operations.
 Add a device by cdev_add() to make it live.
 Test program and printk:
 Before write module, we need to know what this module do. So we provide a test
program to test this device.
 You can modify test program and test your module.
 We will check with our test cases.
 In kernel module, you need to write printk to help debug and use dmesg command
to show message.
 To help demo program, your printk must be started with “OS_AS5: function_name:
message”.
 File operations:
 You should write a struct file_ operations to map the operations to functions
in this module.
 And use cdev_init() at module init to bind cdev and file_ operations.
 ioctl:
 In Linux, device provide user mode program ioctl function to change the device
configuration.
 ioctl define many types of operation with switch case to do coordinated work.
 And ioctl use mask to get value from these operation label.
 Here we provide “ioc_hw5.h” to define 6 works.
1) (HW5_IOC_SETSTUID) Set student ID: printk your student ID
2) (HW5_IOCSETRWOK) Set if RW OK: printk OK if you complete R/W function
3) (HW5_IOCSETIOCOK) Set if ioctl OK: printk OK if you complete ioctl function
4) (HW5_IOCSETIRQOK) Set if IRQ OK: printk OK if you complete bonus
5) (HW5_IOCSETBLOCK) Set blocking or non-blocking: set write function mode
6) (HW5_IOCWAITREADABLE) Wait if readable now (synchronize function):
used before read to confirm it can read answer now when use non-blocking
write mode.
 ioctl lables defined in “ioc_hw5.h”
“_IOW(type, nr, size )” is used for an ioctl to write data to the driver. It is to
generate command numbers.
 Demo for ioctl call in user mode:
ioctl(fd, HW5_IOCSETBLOCK, &ret)
 fd: an open file descriptor
 HW5_IOCSETBLOCK: device-dependent request code.
 &ret: an untyped pointer to memory
 write:
 Define a data struct that is passed in write function.
 a is operator: '+', '-', '*', '/', or 'p' (‘p’ means find prime number)
 b is operand 1
 c is operand 2
 Use INIT_WORK() and schedule_work() to queue work to system queue.
 Find Prime operation:
 It finds c-th prime number bigger than b.
(e.g, “1 p 3” means to find 3rd prime number which is bigger than 1, then it should
be 5.)
 And you will feel the I/O latency when execute test program for “100 p 10000” and
“100 p 20000”.
 We will check your blocking and non-blocking IO by observing the delay of the
message printed by test program.
 R/W function packaged in arithmetic function in user mode program.
arithmetic(fd, 'p', 100, 10000);
 fd: an open file descriptor
 p: operator
 100: operand1
 10000: operand2
 Work Routine:
 The work you enqueued should be written in a work routine function in module.
 These work will be processed by another kernel thread.
 computation is written in a work routine in module
 Blocking and Non-Blocking IO:
 The test program can use ioctl to set blocking or non-blocking.
 Your write function in module can be blocking or non-blocking.
 Blocking write need to wait computation completed.
 Non-blocking write just return after queueing work.
 Read function only has blocking, because not queueing work.
 Blocking Write:
 In test program, we just need a write function.
 Do not need another synchronize function.
 But block when writing.
 Blocking write in test program:
 Non- Blocking Write:
 In test program, we can do something after write function.
 Write function return after queueing work, it is non-blocking.
 But need another synchronize function to wait work completed.
 Non-blocking write in test program:
 Interrupt driven IO:
 When implementing blocking write and synchronize function, they use a while loop
busy waiting the interrupt.
 You can use a variable to simulate the interrupt.
 At the final of the work routine function, change this variable as triggering the
interrupt.
 And then, blocking write and synchronize function can exit the while loop.
 DMA Buffer:
 To simulate register and memory on device, you need to kmalloc a dma buffer.
 This buffer is as I/O port mapping in main memory.
 What device do is written in work routine function. This function get data from this
buffer.
 Defined value written into dma buffer:
 In and out functions:
 You need to implement in & out function to access dma buffer just like physical
device.
 out function is used to output data to dma buffer.
 in function is used to input data from dma buffer.
 The 6 in & out functions are definded in module to operate dma_buf:
('c', 's' and 'i' maps with data type ‘char’, ‘short’ and ‘int’)
 Demo usage of in and out functions:
myouti(value, DMAIOCOKADDR)
 value: data you want to write into dma_buffer
 DMAIOCOKADDR: port in dma_buffer
 Data transfer between kernel and user space:
 get_user(x, ptr)
 Get a simple variable from user space.
 x: Variable to store result.
 ptr: Source address, in user space.
 put_user(x, ptr)
 Write a simple value into user space.
 x: Value to copy to user space.
 ptr: Destination address, in user space.
Template structure:
 Makefile is provided:
 Command: make
(It will firstly build your main.c as kernel module “mydev.ko”, insert “mydev.ko”,
and then build “test.c” as executable file “test”.)
 Command: make clean
(It will remove “mydev.ko” and use “dmesg” to list kernel logs that includes
keyword “OS_AS5”)
 “mknod” script is provided:
 Script
 In mknod command: c means character device. Followed two number are
Major and Minor number to specify device.
 You can get available number by MAJOR() and MINOR() macro after
alloc_chrdev_region() in module_init() function.
 Demo of how to use mknod script: (Refer to Tutorial_11 Slide 3 to 6)
 Steps you need to run the template:
 Run “make”
 Run “dmesg” to check available device number
 Run “sudo ./mkdev.sh MAJOR MINOR” to build file node (MAJOR and
MINOR are the available device number checked from previous step)
 Run “./test” to start testing
 Run “make clean” to remove the module and check the messages
 Run “sudo ./rmnod” to remove the file node
 You will get output:
 You should complete module init and exit functions:
 Implement read/write/ioctl operations and arithmetic routine:
Function Requirements (90 points):
 Register a character device when module initialized. (5 points)
 Initialized a cdev and add it to make it alive. (5 points)
 Allocate DMA buffer. (5 points)
 Allocate work routine. (5 points)
 Implement read operation for your device. (10 points)
 Implement write operation for your device. (20 points)
 Implement ioctl setting for your device. (15 points)
 Implement arithmetic routine for your device. (10 points)
 Complete module exit functions. (5 points)
 Update your student ID in test case and make it be print in kernel ioctl. (5 points)
 Run test cases to check write and read operations. (5 points)
Demo Output:
 Test case: (: '+', '-', '*', '/' is for your testing, we will mainly test ‘p’ operation)
 User mode output:
 Kernel mode output:
 Steps for internal executions:
 find major and minor number
 allocate DMA buffer
 ioctl print set and get value
 write to queue work
 arithmetic routine to compute answer
 read to get answer
 free DMA buffer
 unregister device
Bonus (10 points)
 Global View (Bonus)
 Count the interrupt times of input device like keyboard.
 Hint: watch -n 1 cat /proc/ interrupts
 Use request_irq() in module_init to add an ISR into an IRQ number's action list.
 And free_irq() when module_ exit, otherwise kernel panic.
 Please define IRQ_NUM at head of code.
 Demo output:
Report (10 points)
Write a report for your assignment, which should include main information as below:
 How did you design your program?
 What problems you met in this assignment and what is your solution?
 The steps to execute your program.
 Screenshot of your program output.
 What did you learn from this assignment?
Submission
 Please submit the file as package with directory structure as below:
 CSC3150_Assignment_5_Student ID
- Source
o main.c (if you complete bonus, submit only one “main.c”)
o test.c
o ioc_hw5.h
o makefile
o mknod.sh
o rmnod.sh
- Report
 Due date: End (23:59) of 13 Dec, 2018
Grading rules
Completion Marks
Report 10 points
Bonus 10 points
Completed with good
quality
80 ~ 90
Completed accurately 80 +
Fully Submitted
(compile successfully)
60 +
Partial submitted 0 ~ 60
No submission 0
Late submission Not allowed

More products