Linux Device Drivers book notes
Last Updated: December 31, 2018 by Pepe Sandoval
If you find the information in this page useful and want to show your support, you can make a donation
Use PayPal
This will help me create more stuff and fix the existent content...
Processes attend to different tasks and each process can request system resources (CPU time, memory, network connectivity, etc.) The kernel is the executable code in charge of handling these requests
insmod
program and can be unlinked by the rmmod
program.Also referred as Classes of Modules, Type of Device
The role of the operating system is to:
The CPU enforces protection of system software from the applications and the way to implement this it through different operating CPU modalities (levels or rings)
kernel executes in the highest level (supervisor mode), where everything is allowed, whereas applications execute in the lowest level (user mode), where the processor regulates direct access to hardware and unauthorized access to memory.
We usually refer to the execution modes as kernel space and user space. Each mode can have its own memory mapping—its own address space
Unix transfers execution from user space to kernel space whenever an application issues a system call or is suspended by a hardware interrupt
Modules must be Reentrant — it must be capable of running in more than one context at the same time.
Data structures must be carefully designed to keep multiple threads of execution separate, and the code must take care to access shared data in ways that prevent corruption of the data
Most actions performed by the kernel are done on behalf of a specific process
Modules are strongly tied to the data structures and function prototypes defined in a particular kernel version.
Module's code has to be recompiled for each version of the kernel that it is linked to
The kernel will make calls into your module while your initialization function is still running.
Consider what happens if your initialization function decides to fail, but some part of the kernel is already making use of a functionality your module has registered
It's a table that contains the addresses of global kernel items (functions and variables)
When a module is loaded, any symbol exported by the module becomes part of the kernel symbol table which can be used by other modules
initialization function registers any functionality offered by the module
sys/module
is a sysfs
directory hierarchy containing information on currently-loaded modules
There's list of repositories that is in a file that can be used to install a package so we use apt-get update so that the head of each repo in that list points to the most recent commit of that repo to add a repo we use PPAs (personal package archives) which are identifiers of repos sudo add-apt-repository ppa:
Most of the fundamental driver operations involve three important kernel data structures: file_operations, file, and inode
struct module *owner
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char _ _user *, size_t, loff_t *);
ssize_t (*aio_read)(struct kiocb *, char _ _user *, size_t, loff_t);
ssize_t (*write) (struct file *, const char _ _user *, size_t, loff_t *);
ssize_t (*aio_write)(struct kiocb *, const char _ _user *, size_t, loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int);
int (*aio_fsync)(struct kiocb *, int);
int (*fasync) (int, struct file *, int);
ssize_t (*readv/*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*sendfile)(struct file *, loff_t *, size_t, read_actor_t, void *);
ssize_t (*sendfile)(struct file *, loff_t *, size_t, read_actor_t, void *);
Asynchronous operations might or might not complete before their function returns.
The file structure represents an open file
It is created by the kernel on open and is passed to any function that operates on the file.
After all instances of the file are closed, the kernel releases the data structure
Fields
mode_t f_mode;
loff_t f_pos;
unsigned int f_flags;
struct file_operations *f_op;
void *private_data;
struct dentry *f_dentry;
The inode structure is used by the kernel internally to represent files.
There can be numerous file structures representing multiple open descriptors on a single file, but they all point to a single inode structure
dev_t i_rdev;
struct cdev *i_cdev;
user space & kernel space addresses
User space pointer cannot be dereferenced
user-space memory is paged (it might not be in RAM )
sysfs dev proc sys
parallel port driver modules? kernel mode and user mode memory is paged? a page fault? system call?
/proc ? device nodes?
FS = a way of organizing data on a physical medium Network interface =
some types of drivers work with additional layers of kernel support functions for a given type of device
It is also possible to disable the loading of kernel modules after system boot via the capability mechanism
_ _init
and _ _initdat
tokens are hints to the kernel that the given function or data are only used used only at initialization time then the module loader drops the function or data loaded, making its memory available for other uses.
cat /proc/version
If you find the information in this page useful and want to show your support, you can make a donation
Use PayPal
This will help me create more stuff and fix the existent content...