ETH 780 Information Security

Download Report

Transcript ETH 780 Information Security

uClinux course
Day 5 of 5 - the debugger (gdb) and
uClinux device drivers
1
gdb overview


Gdb stands for Gnu debugger
It can perform the following functions
+ Start your program, specifying anything that might affect its
behavior.
+ Make your program stop on specified conditions.
+ Examine what has happened, when your program has stopped.
+ Change things in your program, so you can experiment with
correcting the effects of one bug and go on to learn about
another.


Gdb is often packaged with a GUI version such as Insight
which creates a graphical wrapper around gdb
To start gdb in text mode (which we will use for this
course) add the following switch to all gdb commands
+ gdb -nw
Author: D L Johnson
2
Invoking gdb

Normall gdb is started with the program name as its argument
+ gdb hello
– Make sure that the program was compiled with the –g option
– gcc –g hello.c –o hello


Gdb normally looks for an initialisation file called .gdbinit in the
directory the application is being debugged from.
The initialisation file can setup any gdb configuration options that
are use often. If you don’t want to use it type
+ gdb –nx

Run your program by typing
+ run
+ r

Continue a program after any break by typing
+ continue
+ c
Author: D L Johnson
3
gdb - examining source files

Examining source files
+ list 10
+ l 10
– Prints source code lines cantered around line 10 of the current source
file
+ list function1
– Prints lines centered around the beginning of function function1
+ list
– Continues printing more lines following the previous list command
+ list –
– Prints lines just before the lines last printed
+ set listsize 20
– Changes the number of source lines printed to 20 (default is 10)
Author: D L Johnson
4
gdb - examining source files
+ disas main
– Disassemble source code of function main
+ disas 0x804843e 0x8048448
– Disassemble source code from address 0x804843e to 0x8048448
Author: D L Johnson
5
gdb - Setting breakpoints, watchpoints, catchpoints



Breakpoints make your program stop whenever a certain
point in the program is reached
Watchpoints are special breakpoints that stop your
program when the value of an expression changes
Catchpoints are special breakpoints that stop your
program when a certain kind of event occurs such as
throwing an exception
Author: D L Johnson
6
gdb - breakpoints

Breakpoints are set with the break command or just using
the abbreviation b
+ b myfunction1
– Sets a breakpoint at entry to function myfunction1
+ b +offset or b -offset
– Sets breakpoint offset number of lines forward or backward from
current position
+ b linenum
– Sets a breakpoint at linenum in the current source file
+ b filename:linenum
+ b filename:myfunction1
– As described above but breakpoint is set in file filename
+ b *address
– Set a breakpoint at address address (this can set breakpoints in
programs which fo not have debugging info or source files)
Author: D L Johnson
7
gdb - breakpoints
+ info breakpoints
– Prints a table of all breakpoints that looks as follows

Clearing breakpoints
+ clear
– Delete any breakpoints at the next instruction to be executed
+ clear linenum
– Delete any breakpoints set at specified line linenum
+ delete
+ d
– Delete all breakpoints, watchpoints and catchpoints
+ delete 4
– Delete breakpoint lablelled as breakpoint 4
+ delete 1-5
– Delete breakpoints labelled 1 to 5
Author: D L Johnson
8
gdb - breakpoints

Disabling/enabling breakpoints
+ disable 1
– Disables breakpoint labelled 1 in the breakpoint table shown by the
“info b” command
+ disable 1-4
– Disables breakpoints labelled 1 to 4 in the breakpoint table
+ enable 1
– Enables breakpoint labelled 1 in the breakpoint table
+ enable once 2
– Enables breakpoint labelled 2 and disable subsequent to stopping
program
+ enable delete 1-4
– Enables breakpoints labelled 1-4 and delete subsequent to stopping
program
Author: D L Johnson
9
gdb - breakpoints
+ condition 1 j==2
– Adds condition to breakpoint 1 stating that j must be equal to 2 to stop

Breakpoint command lists
+ break 8 if i>10
+ commands
+ silent
+ printf “i is %d\n",I
+ i += 50
+ cont
+ end
– Sets up a set of commands that are executed at just before line 8 is executed
if that value of I is greater than 10, it will print the value of I and modify it by
adding 50, it will also continue execution of the program
Author: D L Johnson
10
gdb - Continuing and stepping

Continuing and stepping
+ continue
+ c
– Resume program execution at address where program last stopped
+ step
+ s
– Continue running program until control reaches a different source line
+ step 10
– Continue as in step, but do so 10 times
+ next
+ n
– Continue next source line in the current stack frame. Ie. If there is a call into a
function only stop when returning from this function call.
Author: D L Johnson
11
gdb - Continuing and stepping
+ next 10
– Continue as in next, but do so 10 times
+ finish
– Continue running until just after function in selected stack frame
returns
+ until
+u
– When reaching end of loop after single stepping through it, until makes
the program continue execution until it exits the loop
+ stepi
+ si
– Execute one machine instruction at a time (often useful to fo ‘display/I
$pc’ when stepping through machine instructions – this makes gdb
display next instruction to be executed
Author: D L Johnson
12
gdb - Examining data

Examining data
+ print i
+ p i
– Print the contents of variable I

Formatting data
x
Regard the bits of the value as an integer, and print the integer
in hexadecimal.
d
Print as integer in signed decimal.
u
Print as integer in unsigned decimal
o
Print as integer in octal
t
Print as integer in binary. The letter `t' stands for "two“
c
Regard as an integer and print it as a character constant.
f
Regard the bits of the value as a floating point number and
print using typical floating point syntax.
a
Author: D L Johnson
Print as an address, both absolute in hexadecimal and as an
offset from the nearest preceding symbol. You can use this
format used to discover where (in what function) an unknown
address is located:
13
gdb - Examining data

Example
+ p/x i
– prints the value of variable I as hexadecimal

Examining a block of memory
+ x 0x80483bc
– Displays single memory address contents 0x80483bc with disasembly
+ x/nfu addr
– n = repeat count
– f = display format - (i = instructions, x = hex)
– u = unit size (b-bytes, h=2 bytes, w=4 bytes, g=8 bytes)
+ x/100xw 0x80483bc
– Display 100 2 bytes (word) blocks of memory in hex starting at
0x80483bc
Author: D L Johnson
14
gdb - Automatic display

Automatic display
+ display expr
– displays value of expr after each line is executed
+ display addr
– displays contents of addr after each line is executed
+ display i+j
– displays value of I+j after each line line is executed
+ info display
– Shows list of all expressions to display automatically
+ delete display dnum
+ disable display dnum
+ enable display dnum
– delete,disable or enable display dnum
Author: D L Johnson
15
gdb - registers

Registers
+ info registers
– print the name and values of all registers except floating point registers
+ info all-registers
– print the name and values of all registers, including floating-point
+ info registers regname
– print the value of register regname

Standard register names
+ p/x $pc
– prints the program counter in hex
+ p/i $pc
– prints the next instruction to be executed
+ p/x $sp
– prints the stack pointer in hex
Author: D L Johnson
16
gdb - various

Back tracing
+ backtrace
+ bt
– prints a back trace of the entire stack

information on symbols
+ whatis myvar
– prints the data type of variable myvar
+ info address symbol
– Describe where the data for symbol is stored

Continuing at a different address
+ jump 14
– continue execution at line 14 of current code
+ jump *0x8048473
– Continue execution at address 0x8048473
Author: D L Johnson
17
Unix Device drivers
Author: D L Johnson
18
Unix Device drivers - overview

Key issues when writing device drivers
+ Write kernel code to access the hardware, don’t force particular
policies on the user as different users have different needs
+ The driver should deal with making hardware available
+ Leave issues about how to use the hardware to the applications
+ Occasionally policy decisions are made to simplify user
applications such as offering byte-wide access to hardware
instead of having to handle individual bits
+ Drivers should have the following characteristics
– support synchronous and asynchronous operation
– can be opened multiple times
– exploit full capabilities of the hardware
Author: D L Johnson
19
Unix Device drivers - Splitting the kernel




In a Unix system, several concurrent processes attend to
different tasks.
Each process asks for system resources such as computing
power, memory, network connectivity etc.
The kernel is the big chunk of executable code in charge of
handling all such requests. Though the distinction between the
different
the kernels role can be split into the following parts:
+ Process management: Create and destroy processes, handle
their connection to the outside world and communication among
different processes through signals, pipes etc. The scheduler
controls how processes share the CPU
+ Memory management: calls such as malloc/free need to
intelligently use the memory of the system to avoid memory
holes or inefficient use of memory
Author: D L Johnson
20
Unix Device drivers - Splitting the kernel
+ File systems: Unix is based heavily on a filesystem concept:
almost everythin in Unix can be trated as a file. The kernel
builds a structured filesystem on top of unstructured hardware
(example filesystems are FAT and ext2)
+ Device control: Almost every system operation eventually maps
to a physical device. All device control operations are performed
by device driver code which is specific to the device being
addressed (keyboards, mice, network cards) with the exception
of the processor and memory.
+ Networking: Also managed by the operating system as most
network operation are not specific to a process: incoming
packets are asynchronous events. These packets must be
collected identified and dispatched before a process takes care
of them.
Author: D L Johnson
21
Unix Device drivers - Splitting the kernel
Author: D L Johnson
22
Unix device drivers - Classes of devices

Character devices
+ This is a device that can be accessed as a stream of bytes (like
a file). The text console (/dev/console) and the serial ports
(/dev/ttyS0) are examples of char devices. Unlike files these
devices are characterised by sequential access

Block devices
+ A block device is a device that can host a file system such as a
disk. It can only be accessed as multiples of a block where a
block is usually a power of 2 block such as a kilobyte. Random
access is possible on block devices.

Network interfaces
+ Not really a device - any network transaction is made through
an interface, which is able to exchange data with other hosts.
Communication between kernel and network device is
completely different from that used with char and block devices
- it uses functions related to packet transmission.
Author: D L Johnson
23
Unix device drivers - Building and running modules

The following code is a “hello world” module which will
be loaded into the kernel
+
+
+
+
#define MODULE
#include <linux/module.h>
int init_module(void) { printk("<1>Hello, world\n"); return 0; }
void cleanup_module(void) { printk("<1>Goodbye cruel world\n");
}
– printk prints kernel level messages
– The string <1> is the priority of the message

You can test the module by inserting or removing it from
the kernel
+ root# gcc -c hello.c
+ root# insmod ./hello.o
+ Hello, world
+ root# rmmod hello
+ Goodbye cruel world
Author: D L Johnson
24
Unix device drivers - Building and running modules

Difference between a module and an application
+ Applications performs a single task from begnning to end
+ Applications call functions they don’t define and resolve
externals at linking stage using the appropriate library - printf
uses libc for example
+ A module registers itself in order to serve future requests
+ A module is linked into the kernel and the only functions it can
use are the ones exported by the kernel - printk is defined
within the kernel
Author: D L Johnson
25
Unix device drivers - kernel modules
Author: D L Johnson
26
Unix device drivers - char driver




Devices are accessed through names in the file system
The device files or nodes are located in the /dev directory
Character devices are identified by a ‘c’ in the first
column of the output of a ls -l
Block devices are also located in the /dev/ directory and
are identified by a ‘b’ in the first column
Author: D L Johnson
27
Unix device drivers - char driver




You will also have noticed two numbers (seperated by a
comma) in the output of a ls -l command
These numbers are the major device number and the
minor device number
The major number identifies the driver associated with
the device (e.g. device 3 is a tty device)
It is common for a driver to control several devices; the
minor number provides a way to differentiate among
them
Author: D L Johnson
28
Unix device drivers - char driver


For the driver to be used, the driver node must exist as a
file in the /dev directory
This is done using the following command
+ mknod /dev/button0 c 254 0
– This will make a character device called button0 whose major number
is 254 and whose minor number is 0

You can also view all the major numbers that are
currently assigned to devices using
+ vi /proc/devices

You can request dynamic assignment of a major numbers
in your code but you will have to first check which majot
numbers were assigned before making the file nodes
Author: D L Johnson
29
Unix device drivers - char driver


Char Device drivers in uClinux are written in the following
directory: linux-2.4.x/drivers/char
Device drivers will use low level hardware addresses to
communicate with the hardware, for the Atmel AT91
processor these are found in
+ linux-2.4.x/include/asm-armnommu/arch-atmel
+ for example in hardware.h
– #define
– #define
– #define
– #define
– #define
– #define
– #define
– #define
Author: D L Johnson
ARM_CLK
(32768000)
AT91_USART_CNT 2
AT91_USART0_BASE
(0xfffd0000)
AT91_USART1_BASE
(0xfffcc000)
AT91_TC_BASE (0xfffe0000)
AIC_BASE
(0xfffff000)
AT91_PIOA_BASE (0xffff0000)
AT91_SF_CIDR (0xfff00000)
30
Unix device drivers - char driver
The function which make up a device driver are as follows:
module_init(myfunction_init)
module_exit(myfunction_exit)
myfunction_init
myfunction_exit
register_chrdev(<major_num>,<name>,<fops>)
unregister_chrdev(unsigned int major, const char *name);
major_num = new major number of device ( use 0 to auto allocate)
name = name of device
fops =file operations to perform on device
major_num = major number of device
name = name of device
request_irq (IRQ_NUM, irq_function, flags, dev_name, dev_id)
IRQ_NUM = interrupt number being requested
irq_function = pointer to function to handle interupt
flags = interupt type eg. SA_INTERRUPT = fast interrupt handler
dev_name = name that will show in /proc/interrupts
dev_id = pointer used for shared irq's set to NULL for no sharing
Author: D L Johnson
free_irq (IRQ_NUM, dev_id)
IRQ_NUM = interrupt number being requested
dev_id = pointer used for shared irq's set to NULL for no sharing
31
Unix device drivers - char driver
struct file_operations <fops> = {
read: myfunction_read
write: myfunction_write
ioctl: myfunction_ioctl
}
ssize_t myfunction_read(struct file *filep, char *buff, size_t
count, loff *offp)
ssize_t myfunction_write(struct file *filep, char *buff, size_t
count, loff *offp)
*filep = file pointer of device
*buff = user buffer holding area to write to
count = number of bytes in buffer
offp = indicates the file positions
*filep = file pointer of device
*buff = user buffer holding area to read from
count = number of bytes in buffer
offp = indicates the file positions
copy_to_user (*to_buffer, *from_buffer, count)
Author: D L Johnson
copy_from_user (*to_buffer, *from_buffer, count)
32


A new system to register devices has been introduced
into the kernel 2.4.x called the device filesystem
The main advantages of devfs are as follows:
+ Device entry points in /dev are created at device
initialization and removed at device removal.
+ The device driver can specify device names, ownership, and
permission bits, but user-space programs can still change
ownership and permission (but not the filename).
+ There is no need to allocate a major number for the device
driver and deal with minor numbers.

This can be called with
– devfs_handle_t devfs_register (devfs_handle_t dir, const char *name,
unsigned int flags, unsigned int major, unsigned int minor, umode_t
mode, void *ops, void *info);

or simplified with a wrapper function
– misc_register(minor_num, name, fops)
Author: D L Johnson
33
Unix device drivers - armbutton code

















/*
*
*
*
*/
ARM Button Driver
Copyright (C) CSIR
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
David Johnson 2003
<linux/config.h>
<linux/module.h>
<linux/kernel.h>
<linux/sched.h>
<linux/interrupt.h>
<linux/time.h>
<linux/timer.h>
<linux/fs.h>
<linux/miscdevice.h>
<linux/string.h>
<linux/errno.h>
<linux/init.h>

#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/mach-types.h>

#include "armbutton.h"

static DECLARE_WAIT_QUEUE_HEAD(button_wait_queue); /* Used for blocking read */
static char button_output_buffer[32];
/* Stores data to write out of device */
static int bcount;
/* The number of bytes in the buffer */











/*
*
*
*
*
*
*/
This handler is called when the orange button is pressed (GPIO 10 of the
SuperIO chip, which maps to logical IRQ 26). If the press_count is 0,
this is the first press, so it starts a timer and increments the counter.
If it is higher than 0, it deletes the old timer, starts a new one, and
increments the counter.
Author: D L Johnson
34
Unix device drivers - armbutton code



































static void button_handler (int irq, void *dev_id, struct pt_regs *regs)
{
bcount = sprintf(button_output_buffer, "button pressed");
wake_up_interruptible (&button_wait_queue);
}
/*
* This function is called when a user space program attempts to read
* /dev/armbutton. It puts the device to sleep on the wait queue until
* button_sequence_finished writes some data to the buffer and flushes
* the queue, at which point it writes the data out to the device and
* returns the number of characters it has written. This function is
* reentrant, so that many processes can be attempting to read from the
* device at any one time.
*/
static int button_read (struct file *filp, char *buffer,
size_t count, loff_t *ppos)
{
interruptible_sleep_on (&button_wait_queue);
return (copy_to_user (buffer, &button_output_buffer, bcount))
? -EFAULT : bcount;
}
/*
* This structure is the file operations structure, which specifies what
* callbacks functions the kernel should call when a user mode process
* attempts to perform these operations on the device.
*/
static struct file_operations button_fops = {
owner:
THIS_MODULE,
read:
button_read,
};
/*
* This structure is the misc device structure, which specifies the minor
* device number (158 in this case), the name of the device (for /proc/misc),
* and the address of the above file operations structure.
*/
Author: D L Johnson
35
Unix device drivers - armbutton code















static struct miscdevice button_misc_device = {
BUTTON_MINOR,
"armbutton",
&button_fops,
};
/*
* This function is called to initialise the driver, either from misc.c at
* bootup if the driver is compiled into the kernel, or from init_module
* below at module insert time. It attempts to register the device node
* and the IRQ and fails with a warning message if either fails, though
* neither ever should because the device number and IRQ are unique to
* this driver.
*/
static int __init armbutton_init(void)
{
printk (KERN_INFO "ARM Button Driver Version %s (C) CSIR "
"David Johnson 2003.\n", VERSION);


if (misc_register (&button_misc_device)) {
printk (KERN_WARNING "armbutton: Couldn't register device 10, "
"%d.\n", BUTTON_MINOR);
return -EBUSY;
}





if (request_irq (IRQ_EXT0, button_handler, SA_INTERRUPT,
"armbutton", NULL)) {
printk (KERN_WARNING "armbutton: IRQ %d is not free.\n",
IRQ_PIOA);
misc_deregister (&button_misc_device);
return -EIO;
}
return 0;









}
Author: D L Johnson
36
Unix device drivers - armbutton code










static void __exit armbutton_exit (void)
{
free_irq (IRQ_PIOA, NULL);
misc_deregister (&button_misc_device);
}
MODULE_AUTHOR("David Johnson");
MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;
module_init(armbutton_init);
module_exit(armbutton_exit);
Author: D L Johnson
37
Assignment 5

Create a device driver which controls any of the 4 LED’s
on the Atmel EB40 board
+ Hint the EB40 board uses the following lines for its LEDs
– PIOA_TI0A0 RED
– PIOA_TIOA1 AMBER
– PIOA_TI0B0 GREEN

You can use a ioctl method or the write method to set the
LED’s
Author: D L Johnson
38