kernel modules
play

Kernel Modules KLD Device Drivers The kld interface allows system - PDF document

Dynamic Kernel Linker Facility - Kernel Modules KLD Device Drivers The kld interface allows system administrators to dynamically add and remove functionality from a Pseudo device example running system. Joystick device example This


  1. Dynamic Kernel Linker Facility - Kernel Modules KLD Device Drivers • The kld interface allows system administrators to dynamically add and remove functionality from a Pseudo device example running system. Joystick device example • This allows device driver writers to load their new changes into a running kernel without constantly rebooting to test changes. • kld interface is used through the following privileged commands: – kldload - loads a new kernel module – kldunload - unloads a kernel module – kldstat - lists the currently loaded modules The loader Skeleton Layout of a kernel module /* * Load handler that deals with the loading and unloading of a KLD. */ /* * KLD Skeleton * Inspired by Andrew Reiter's Daemonnews article */ #include <sys/types.h> static int skel_loader(struct module *m, int what, void *arg) #include <sys/module.h> { #include <sys/systm.h> /* uprintf */ int err = 0; #include <sys/errno.h> switch (what) { #include <sys/param.h> /* defines used in kernel.h */ #include <sys/kernel.h> /* types used in module initialization */ case MOD_LOAD: /* kldload */ uprintf("Skeleton KLD loaded.\n"); / * Load handler that deals with the loading and unloading of a KLD. */ break; static int skel_loader(struct module *m, int what, void *arg) case MOD_UNLOAD: { int err = 0; uprintf("Skeleton KLD unloaded.\n"); switch (what) { break; case MOD_LOAD: /* kldload */ default: uprintf("Skeleton KLD loaded.\n"); break; err = EINVAL; case MOD_UNLOAD: uprintf("Skeleton KLD unloaded.\n"); break; default: err = break; EINVAL; break; } return(err); } /* Declare this module to the rest of the kernel */ static } moduledata_t skel_mod = { "skel", skel_loader, NULL }; DECLARE_MODULE(skeleton, skel_mod, SI_SUB_KLD, SI_ORDER_ANY); return(err); } } Declaring the module Compiling and Loading • The makefile should look like: /* Declare this module to the rest of the kernel */ SRCS=skeleton.c KMOD=skeleton static moduledata_t skel_mod = .include <bsd.kmod.mk> { "skel", skel_loader, NULL }; • Running make with this makefile will DECLARE_MODULE(skeleton, skel_mod, create a file skeleton.ko SI_SUB_KLD, SI_ORDER_ANY); • It can be loaded into your system by typing: # kldload -v ./skeleton.ko 1

  2. what's in a mode Special Files struct stat { dev_t st_dev; /* inode's device */ • hardware devices have file names. ino_t st_ino; /* inode's number */ mode_t st_mode; /* inode protection mode */ – /dev/tty nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of the file's owner */ – /dev/ad0s1a gid_t st_gid; /* group ID of the file's group */ – /dev/zero dev_t st_rdev; /* device type */ ... • may be accessed by the same system calls } used for regular files ... #define S_ISDIR(m) ((m & 0170000) == 0040000) /* directory */ • created by the mknode system call. #define S_ISCHR(m) ((m & 0170000) == 0020000) /* char special */ #define S_ISBLK(m) ((m & 0170000) == 0060000) /* block special */ • MAKEDEV script. #define S_ISREG(m) ((m & 0170000) == 0100000) /* regular file */ #define S_ISFIFO(m) ((m & 0170000) == 0010000 || \ • can be: (m & 0170000) == 0140000) /* fifo or socket */ #ifndef _POSIX_SOURCE – structured - blocked oriented #define S_ISLNK(m) ((m & 0170000) == 0120000) /* symbolic link */ #define S_ISSOCK(m) ((m & 0170000) == 0010000 || \ – unstructured - character oriented (m & 0170000) == 0140000) /* fifo or socket */ #define S_ISWHT(m) ((m & 0170000) == 0160000) /* whiteout */ #endif ... from /usr/include/sys/stat.h % ls -ls /dev ... Device number (major – minor) 0 crw-r----- 2 root operator 116, 0x00010002 Mar 18 2002 ad0 0 crw-r----- 2 root operator 116, 0 Mar 18 2002 ad0a 0 crw-r----- 2 root operator 116, 1 Mar 18 2002 ad0b 0 crw-r----- 2 root operator 116, 2 Mar 18 2002 ad0c • inode has the major/minor number 0 crw-r----- 2 root operator 116, 3 Mar 18 2002 ad0d 0 crw-r----- 2 root operator 116, 4 Mar 18 2002 ad0e – st_rdev 0 crw-r----- 2 root operator 116, 5 Mar 18 2002 ad0f 0 crw-r----- 2 root operator 116, 6 Mar 18 2002 ad0g • major number 0 crw-r----- 2 root operator 116, 7 Mar 18 2002 ad0h ... 0 crw-r----- 2 root operator 13, 8 Mar 18 2002 da1a – identifies the driver 0 crw-r----- 2 root operator 13, 9 Mar 18 2002 da1b ... – used by the kernel to find the driver 0 crw-r----- 1 root kmem 2, 0 Mar 18 2002 mem 0 crw-rw-rw- 1 root wheel 67, 0 Jul 22 2002 meteor0 • minor number 0 crw-rw-rw- 1 root wheel 30, 2 Mar 18 2002 midi0 0 lrwxrwxrwx 1 root wheel 6 Mar 18 2002 mixer -> mixer0 – identifies a sub-unit - disk n, tape n 0 crw-rw-rw- 1 root wheel 30, 0 Mar 18 2002 mixer0 0 lrwxr-xr-x 1 root wheel 8 Mar 20 2002 mouse -> sysmouse – sets some flags/options ... 0 crw-rw-rw- 1 root wheel 2, 12 Mar 18 2002 zero – used by the driver major device number minor device number Major Minor numbers Device Driver • crw-rw-rw- 1 root wheel 2, 2 Apr 17 06:16 /dev/null • crw-r--r-- 1 root wheel 2, 3 Oct 27 17:26 /dev/random • autoconfiguration and initialization • crw-rw-rw- 1 root wheel 2, 12 Oct 27 17:26 /dev/zero • routines to service I/O requests • crw------- 1 root wheel 28, 0 Oct 27 17:26 /dev/ttyd0 – invoked via system call. • crw------- 1 root wheel 28, 1 Oct 27 17:26 /dev/ttyd1 • crw------- 1 root wheel 28, 2 Oct 27 17:26 /dev/ttyd2 – executes synchronously • crw------- 1 root wheel 28, 3 Oct 27 17:26 /dev/ttyd3 – top half of the driver • 0 crw-r----- 2 root operator 116, 0 Oct 27 17:26 /dev/ad0a • interrupt service routines • 0 crw-r----- 2 root operator 116, 1 Oct 27 17:26 /dev/ad0b • 0 crw-r----- 2 root operator 116, 2 Oct 27 17:26 /dev/ad0c – invoked by the hardware fielding an interrupt. • 0 crw-r----- 2 root operator 116, 3 Oct 27 17:26 /dev/ad0d – bottom half of the driver 2

  3. kernel mode trap handler lea 0x5,%eax int $0x80 if (code >= p->p_sysent->sv_size) callp = &p->p_sysent->sv_table[0]; kernel mode the system call else callp = &p->p_sysent->sv_table[code]; handler ... system-call narg = callp->sy_narg & SYF_ARGMASK; user mode ... handler error = (*callp->sy_call)(p, args); int #include <fcntl.h> open(p, uap) #include <sys/joystick.h> struct proc *p; #define DEVJOY "/dev/joy0" register struct open_args /* { ... open the open syscallarg(char *) path; syscallarg(int) flags; main(int cc, char **vv) system-call system call { syscallarg(int) mode; int fd; } */ *uap; handler { if((fd = open(DEVJOY, O_RDONLY)) < 0) { perror(DEVJOY); ... exit(1); return ( spec_open(...)); } special file open from /usr/include/sys/conf.h struct cdevsw { spec_open(ap) d_open_t *d_open; struct vop_open_args /* { d_close_t *d_close; struct vnode *a_vp; d_read_t *d_read; int a_mode; d_write_t *d_write; struct ucred *a_cred; d_ioctl_t *d_ioctl; struct proc *a_p; d_poll_t *d_poll; } */ *ap; d_mmap_t *d_mmap; { d_strategy_t *d_strategy; struct proc *p = ap->a_p; struct vnode *vp = ap->a_vp; const char *d_name; /* base device name, dev_t dev = vp->v_rdev; e.g. 'vn' */ int error; int d_maj; d_dump_t *d_dump; dsw = devsw(dev); d_psize_t *d_psize; u_int d_flags; if ( (dsw == NULL) || (dsw->d_open == NULL)) int d_bmaj; return ENXIO; /* additions below are not binary ... compatible with 4.2 and below */ error = (*dsw->d_open)(dev, ap->a_mode, S_IFCHR, p); d_kqfilter_t *d_kqfilter; }; if (error) return (error); Device driver - sections /* * this file is created by 'mkconf.c' */ int (*bdevsw[])() { • kernel interface: needed for auto-configuration &nulldev, &nulldev, &rkstrategy, &rktab, /* 0 - rk */ &nodev, &nodev, &nodev, 0, /* 1 - rp */ ... – probe/attach 0 }; • user interface int (*cdevsw[])() { &klopen, &klclose, &klread, &klwrite, &klgstty, /* 0 - console */ – open/close &pcopen, &pcclose, &pcread, &pcwrite, &nodev, /* 1 - pc */ &lpopen, &lpclose, &nodev, &lpwrite, &nodev, /* 2 - lp */ ... – read/write &nulldev, &nulldev, &rkread, &rewrite, &nodev, /* 33 - rk */ ... – ioctl 0 }; – poll/select/map 3

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend