Looking at kernel objects - PowerPoint PPT Presentation

About This Presentation
Title:

Looking at kernel objects

Description:

MODULE_LICENSE( GPL ); dram.c module_init() module_exit() my_read() some header-files some global data this module s payload (its ... – PowerPoint PPT presentation

Number of Views:50
Avg rating:3.0/5.0
Slides: 26
Provided by: CRU7
Learn more at: https://www.cs.usfca.edu
Category:
Tags: dram | kernel | looking | objects

less

Transcript and Presenter's Notes

Title: Looking at kernel objects


1
Looking at kernel objects
  • How a character-mode Linux device driver can be
    useful in viewing a net_device structure

2
Our /proc/netdevs pseudo-file
  • We wrote a Loadable Kernel Module that creates a
    pseudo-file allowing users to see some
    information about the kernels data

struct net_device
struct net_device
struct net_device
lo
eth0
eth1
3
The LKMs source-code
netdevs.c
include ltlinux/module.hgt include
ltlinux/proc_fs.hgt char modname
netdevs MODULE_LICENSE(GP
L)
some header-files
some global data
my_get_info()
this modules payload function
module_init()
required module administration
functions
module_exit()
4
User-space/Kernel-space
user-space (restricted privileges)
kernel-space (unrestricted privileges)
operating system kernel
LINUX
open read write (etc)
standard runtime library
application program
cat
netdevs.ko
installable module
privilege barrier
5
Linux device drivers
  • There is another kind of LKM, written to control
    the systems hardware devices rather than merely
    to expose information
  • Its code-structure will depend on the type of
    hardware device it is intended to control
  • character devices
  • block devices
  • network interface devices

6
Hardwares operations
  • In order to write the software that controls a
    particular device, the programmer needs to know
    details about its capabilities and about its
    mechanisms for being controlled
  • This information is found in programming manuals,
    produced by the manufacturer
  • These manuals may or not be available to the
    general public (often are proprietary)

7
A few devices are simple
  • If a particular devices operations are very
    simple to understand, we may not need to consult
    the manufacturers documentation (just use
    common sense and guesswork)
  • EXAMPLE The computer systems main memory offers
    us an easy-to-understand hardware component for
    which we can directly write a device-driver
    module

8
dram.c
  • Two benefits of having a device-driver for the
    computers physical memory are
  • We can directly look at kernel data-structures
    using unprivileged application-programs
  • We get to see the general code-structure for
    Linux device-drivers in the simplest of cases

9
Using our fileview utility
  • Our previous netdevs.c module tells us where
    the struct net_device objects are located in
    our systems physical memory
  • So we can use fileview to inspect these kernel
    data-structures once weve loaded our dram.ko
    device-driver into the kernel

Timeout for an in-class demonstration
10
The code-structure for dram.c
dram.c
include ltlinux/module.hgt include
ltlinux/highmem.hgt char modname dram int
my_major 85 MODULE_LICENSE(
GPL)
some header-files
some global data
this modules payload (its method
functions and its file_operations
structure)
my_read()
my_llseek()
my_fops
module_init()
required module administration
functions
module_exit()
11
Kernels helper-functions
  • The Linux kernel provides quite a few aids to the
    authors of device-driver code
  • register_chrdev() and unregister_chrdev()
  • copy_to_user() and copy_from_user()
  • kmap() and kunmap()
  • The kernel also exports some of its global
    variables (which drivers can reference)
  • num_physpages and mem_map

12
Memory-mapping
persistent mapping transient mappings
kernel space
HMA
user space
896-MB
physical RAM
There is more physical RAM in our classrooms
systems than can be mapped into the
available address-range for kernel virtual
addresses
CPUs virtual address-space
13
What does kmap() do?
  • The kmap() helper-function allows your driver
    to create a temporary mapping for any one 4-KB
    page of physical memory to some unused virtual
    address in kernel-space, then later kunmap()
    lets your driver discard that mapping when its
    no longer needed (so there will be available that
    kernel-address for later reuse)

14
The mem_map array
  • The kernel creates an array of structures, named
    mem_map , whose entries hold detailed
    information about how each 4KB page of physical
    RAM is now being used
  • The global variable named phys_mem stores the
    total number of array-entries, and hence can be
    used by your driver to determine the amount of
    installed RAM

15
The function-prototypes
void kmap( struct page page_ptr ) This
function accepts a pointer to an entry of type
struct page in the kernels mem_map
array, and returns a kernel address where that
page of physical RAM has been temporarily mapped
void kunmap( void virt_addr ) This function
accepts an address where the kernel temporarily
has mapped a page of physical RAM and it deletes
that mapping, thus freeing the address for reuse
later when the kernel is asked to setup a
different temporary mapping of physical RAM into
kernel-space
16
Our driver read() method
  • It has to support the traditional stream-of-bytes
    paradigm, so a sanity check will be needed for
    the callers argument-values

ssize_t my_read( struct file file, char buf,
size_t count, loff_t pos )
number of bytes that caller wants to read
the current position of the file-pointer
// Theres nothing to be read beyond the
end of physical RAM if ( pos gt dram_size
) return 0
Physical RAM
dram_size
pos
17
read() method (continued)
  • Our driver has to accommodate the CPUs
    page-granular memory-architecture, and the
    kmap() functions ability to map
    one-page-at-a-time

pos
int page_number pos / PAGE_SIZE
int page_indent pos PAGE_SIZE if (
page_indent count gt PAGE_SIZE ) count
PAGE_SIZE page_indent struct page pp
mem_map page_number void from kmap( pp
) page_indent int more copy_to_user( buf,
from, count )
18
Another argument-value pitfall
  • It is possible that the caller did not supply a
    large-enough buffer for the amount of data that
    is supposed to be transferred
  • That potential buffer-overflow problem could
    be detected during execution of the
    copy_to_user() helper-function, if fewer than
    count bytes can be copied without triggering a
    segmentation violation

19
The drivers solution
  • The copy_to_user() function return the number
    of bytes that remain to be copied (normally this
    is zero all copying got done)
  • But if its NOT zero, the drivers duty is to
    notify the user that a segmentation fault error
    occurred but AFTER kunmap()

int more copy_to_user( buf, from, count
) // first unmap the page, then notify the
user if necessary kunmap( pp ) if ( more )
return EFAULT
20
The llseek() method
  • Our dram.c driver needs to implement its own
    llseek() function, in order to allow an
    application-program to seek to the end of the
    device-file (so it will know what total amount of
    physical RAM is installed)
  • This feature is used by our fileview tool when
    a user hits the ltENDgt-key, and to display the
    total size for the device-file

21
llseek() implementation
unsigned int dram_size // equals PAGE_SIZE
num_physpages loff_t my_llseek( struct file
file, loff_t offset, int whence )
loff_t newpos -1 switch ( whence
) case 0 newpos offset break //
SEEK_SET case 1 newpos file-gtf_pos offset
break // SEEK_CUR case 2 newpos dram_size
offset break // SEEK_END if ((
newpos lt 0 )( newpos gt dram_size )) return
EINVAL file-gtf_pos newpos return newpos
22
Demo vwnetdev.cpp
  • This application makes use of information from
    the /proc/netdevs pseudo-file, plus the
    information that can be read from the computers
    physical memory using the capabilities
    implemented by our dram.c device-driver
  • It lets a user view the struct net_device
    object for a specified network-interface

23
Our offsets.c module
  • This module creates a pseudo-file that can help a
    user to interpret the hexadecimal output produced
    by vwnetdev
  • It shows the locations within a net_device
    structure for some structure-members of
    particular significance for network device
    drivers (which we shall explore next time)

24
In-class exercise 1
  • One of the struct net_device fields that is
    significant in a Linux network device driver is
    the get_stats function-pointer field
  • Modify our offsets.c module so that the
    pseudo-file this module creates will include the
    offset for the get_stats member
  • Turn in a printout of the enhanced output
    (created using our ljpages printing tool) be
    sure your name is handwritten on it

25
In-class exercise 2
  • Take a look at our kernels definition for a
    struct net_device object, in header-file
  • lt/usr/src/linux/include/linux/netdevice.hgt
  • and identify three additional member-fields
    that you would like to show the offsets for
  • Then implement the display of those three offsets
    (by adding code to our offsets.c)
Write a Comment
User Comments (0)
About PowerShow.com