Tuesday, July 31, 2007

Character Device Operation

We basically do two simple things with devices, read and write. To implement a character device, we need to open the device and then close it when we re done. Linux treats devices as file systems. We do create a file, read/write in it then close the file in C/C++. We have to do the same here for devices.

NOTE: The texts below are copied from an unknown source, if anyone know it's sources, let me know - I'll acknowledge them.

This blog is for personal study purpose only and do not have any affiliation with any group or company.

Opening a char device

A character device driver is first accessed by executing its open() function.
− This function is executed in the sys_open() system call.
− The open() function will just not be called if it is not implemented by a specific device driver. This behavior may be observed in dentry_open().

In the case that a character needs to implement its open() function, it will have to provide the following
functionality:
− Increment the usage count, so that the driver may not be removed from the Kernel (in the case of a module).
− Check for hardware-specific problems associated with this particular device.
− Initialize the hardware, if it is needed.
− Identify the minor number of the device that was open and update the f_op pointer if necessary. This is needed for device sharing the same major number but having different device drivers (i.e., miscellaneous devices).
− Allocate the memory needed for the various data structures used in the device driver and initialize these structures.

Reading characters from device

• read() is called to read data from the device. The form of the read function is as follows:
static ssize_t device_read(struct file * file,
char * buffer, size_t count, loff_t *ppos)
• Note that the arguments of the read() method have changed in the 2.2 and subsequent Kernels.
− The new method passes only a file structure, from which we can find the disk inode associated with the device file.
• The read() method implemented by a device driver should copy the specified number of bytes into the
buffer and return the actual number of bytes read (or an error code).
− The read() function may therefore read less data than was requested. In this case the returned value will be less than size passed in parameter.
− A negative return value means that there was an error.
− Note that the buffer field passed to the device drivers refers to the memory space of the User space process that invoked the read() system call.
− The copy_to_user() function must thus be used in order to return the data in the proper memory segment.
• The following is an example of the structure used in a simple read() method. It was taken from the PC Watchdog driver.
#define TEMP_MINOR 131
static ssize_t pcwd_read(struct file *file, char *buf, size_t count,
loff_t *ppos)
{
unsigned short c;
unsigned char cp;
/* Can't seek on this device, so return an error */
/* if the offset is not the same as current reading position */
if (ppos != &file->f_pos)
return -ESPIPE;
/* Find the minor number associated with the device file*/
switch(MINOR(file->f_dentry->d_inode->i_rdev))
{
/* Go ahead if this is the device we want to handle */
case TEMP_MINOR:
/*
* Convert metric to Fahrenheit, since this was
* the decided 'standard' for the return value.
*/
c = inb(current_readport);
cp = (c * 9 / 5) + 32;
/* Copy the result in User space */
if(copy_to_user(buf, &cp, 1))
return -EFAULT;
/* Only one byte can be read, thus return 1 */
return 1;
/* Return error if wrong minor number */
default:
return -EINVAL;
}
}


Writing to a character device

• The write() method implemented by a driver is invoked to write data to the device. It is defined as
follows:
static ssize_t device_write(struct file *file,
const char *buf, size_t count, loff_t *ppos)
• write() should copy the specified number of bytes from the User space buffer into the device.
− The number of bytes specified by the value of count should be written to the device.
− Similarly to the read() method, the number returned by the write() function should match the value of count. If it’s not the case, the data was partially written or, in the case of a negative value, an error occurred.
• The following is an example of the implementation of a write() function. It does not address hardware issues, which we will reserve for the next chapters.
static ssize_t pcwd_write(struct file *file, const char *buf, size_t
len, loff_t *ppos)
{
/* We can't seek on this device */
if (ppos != &file->f_pos)
return -ESPIPE;
if (len)
{
pcwd_send_heartbeat();
return 1;
}
return 0;
}



Closing a char device

A character device driver is closed when a User space application no longer needs it.
− This function is executed in the sys_close() system call.
− The release() function will not be called if it is not implemented by a specific device driver. This behavior may be observed in fput().
• The release() function is in charge of the following steps:
− It decrements the usage count. This is necessary in order for the Kernel to be able to remove the module.
− Removes any unnecessary data from memory. This is particularly true for data placed in the private_data field of the file structure associated with the device.
− Shut down the physical device if needed. This includes any operation that must be executed in order to leave the hardware in a sane state, and disabling interrupts.
• The release() function associated with a particular driver will not be invoked if the open() function was not called.
− Again, this may be observed in the fput() function.

Monday, July 30, 2007

Linux Device Driver Development Kit (DDK)

I was looking for device driver samples, but I couldn't find any suitable sample on which I can experiment on. Moreover I always knew Linux doesn't have any Device Driver Development Kit (DDK). But the wait is over.

There is a DDK, in fact it is available since May 2006. Here is the announcement of the author.
And here is the DOWNLOAD link.

According to the author,

It is a cd image that contains everything that a Linux device driver author would need in order to create Linux drivers, including a full copy of the O'Reilly book, "Linux Device Drivers, third edition" and pre-built copies of all of the in-kernel docbook documentation for easy browsing. It even has a copy of the Linux source code that you can directly build external kernel modules against.

L A N A N A and LINUX ALLOCATED DEVICES

The Major and Minor numbers are fixed and standard numbers. It is standardized and maintained by The Linux Assigned Names And Numbers Authority (LANANA) and it is a part of Free Standards Group. Regardless which distro it is, these major and minor numbers remain same. New devices can be registered through LANANA.


It is important to know the numbers, it is available in linux documentation. (Documentation/devices.txt)

You may not have this doc installed, so here goes an online link of the latest doc.

Current Linux 2.6+ Device List (Updated 24 July 2007)



Saturday, July 28, 2007

Planning to write a device driver

Planning for writing a device driver on this week. My primary target is to write a driver which would be able to talk to any USB device. The conversations can be very simple. The problem is all devices are recognizable and automatically mounted by linux (like plug n play). I guess I have to remove the mounted device from kernel but not physically, then would be able to use my driver.

These are simply assumptions. Now I am going through few online materials. Here are some useful links.

http://kernelnewbies.org/
http://kernelnewbies.org/Drivers <- this page is like heaven for me!
http://www.linuxplanet.com/linuxplanet/tutorials/1019/
http://www.linuxdevices.com/articles/AT5340618290.html
http://developer.osdl.org/dev/opendrivers/
http://www.tldp.org/HOWTO/IO-Port-Programming.html
http://www2.linuxjournal.com/article/2920

Well there's a totally dedicated site for USB devices

http://www.linux-usb.org/

Dedicated serial driver how-to's
http://www.easysw.com/~mike/serial/serial.html


I am still choosing which device to use. Cell phones can be a good choice. Cell phone manufacturers usually provide windows drivers and applications, but linux users are totally ignored. I may try to write a driver for my cell phone. Which is Motorola branded.
Fortunately Motorola has a developer network, that might be useful
http://developer.motorola.com/

Windows 2003 Server as Workstation

I do a lot of experiments whenever I get time. Sometimes I skip important jobs just to satisfy my mind with my experiments. Well, that can't be good but at least I learn some new things and can sleep at night (actually morning).

This might seem totally offtopic, well it is. But it is related to device drivers and Operating System so interested people, go on.

On last weekend, I took a project of using Windows 2003 Sever as workstation. Windows 2003 is not made for workstations, so it seemed an interested topic for me.

There are several reasons I was interested to use win 2003 on my PC, because
  1. The kernel is new, SP1 kernel was of 2005 and SP2's kernel was of November 2006, comparing to XP, this is supposed be a huge difference.
  2. More stable than XP or any other windows (except vista) as Microsoft says. (Google can't trace this blog, yay!)
  3. Simpler than every way of XP!
  4. I was bored with XP, I am using this since 2002.
  5. I liked the boot screen of 2003 server :D

I have downloaded CD version of Windows 2003 Server R2 SP2 (legit 60 day evaluation copy) from microsoft's web. Google it, its available. Then Downloaded SP2 from same site.

Installation was exactly like XP. After installation, I had to do some tweaking, there are few tutorials to do the tweaks, but my target of this self project was to tweak it by myself. Which turned out to be the same as the online tutorials. In the end, my 2003 server became a totally usable as workstation. Which supports all multimedia extensions with DirectX 9.0c.

All the drivers worked nicely. Even though they warned me there are issues.

Windows Vista (RTM 6.0.6000) does not support my
USB Bluetooth device
Avermedia GO 007 FM (TV tuner)

Windows 2003 Server supports all the devices I have. Without Any issue.
And supports all the softwares and almost all games that runs on XP as well (I don't even care for giving a list).

On this weekend, my OS totally got ruined, as I forgot to install any antivirus, so I had to install other OS over this nice installation of win 2003. :(

THE END

Monday, July 16, 2007

Major and Minor numbers

One of the basic features of the Linux kernel is that it abstracts the handling of devices. All hardware devices look like regular files. They can be opened, closed, read and written using the same, standart system calls that are used to manipulate files.

Every device in the system is represented by a file. For block (disk) and character devices, these device files are created by the mknod command and they describe the device using major and minor device numbers.

The kernel needs to be told how to access the device. Not only does the kernel need to be told what kind of device is being accessed but also any special information, such as the partition number if it's a hard disk or density if it's a floppy, for example. This is accomplished by the major number and minor number of that device.

All devices controlled by the same device driver have a common major device number. The minor device numbers are used to distinguish between different devices and their controllers. Linux maps the device special file passed in system calls (say to mount a file system on a block device) to the device's device driver using the major device number and a number of system tables, for example the character device table, chrdevs. The major number is actually the offset into the kernel's device driver table, which tells the kernel what kind of device it is (whether it is a hard disk or a serial terminal). The minor number tells the kernel special characteristics of the device to be accessed. For example, the second hard disk has a different minor number than the first. The COM1 port has a different minor number than the COM2 port, each partition on the primary IDE disk has a different minor device number, and so forth. So, for example, /dev/hda2, the second partition of the primary IDE disk has a major number of 3 and a minor number of 2.


Reference: The Linux tutorial

Character Drivers and Block Drivers

I am stuck here for over a week. Actually I cannot decide what to do. The materials I have found so far, everybody seems to be concerned to dive into programming stuff rather than describing what is it. Well, I am trying to define some definition stuff without getting into much programming.


Character Devices and character drivers:

Character devices can be accessed as a stream of bytes, and this job is done by character drivers. Which means, the driver can access the device and transfer data as characters. The benefit of this method is, if the device is a sequential access device - character by character data transfer method is the most effective one. And we can use this method almost everything. Even if the device is a random-access device, we can emulate/pretend that the device is a sequential access device.

The serial port is the most familiar and widely used character device (/dev/ttys0). Character devices are represented by file nodes, and all the nodes are mounted on /dev directory. Though this device is treated as a file system, we cannot manipulate this file as conventional file (naturally).


Block devices and block drivers

Block devices are accessed by filesystem nodes just like a char device does (in /dev directory). It is treated like char devices almost in all ways, except one. That is, it trasnfers data by blocks (1KB per block, usually). And that gave the block devices the power of hosting the filesystems itself (disks, storage). Block devices are usually the disks and other storage devices, and virtual filesystems. Block devices are managed by kernel itself.


Here is a little note on linux file systems. click here

A little comparison

So in Linux, devices are treated as files. The benefit is, a common structure can be used for talking to all the devices. The idea nice. Then why do we have block drivers and character drivers. We could have done everything by character drivers. But the problem occurs when the random-access devices comes in. For example, if we use large storage devices, using character drivers won't be efficient, we need block drivers in this case. Again, for a keyboard, using a block driver is useless. So, we need these two distinct drivers.

Tuesday, July 10, 2007

Checklist July 10, 2007

Topics I need to cover next in details are:

1. Character Devices and Block Devices
2. Major Number and Minor Numbers
3. Routines

Linux Device Driver Architecture Components

I have discussed about the module structures before. Now lets have a look on overall linux device driver architecture components. So that we can sort out, what should be the next step of my research work.

Device Drivers as modules

Linux device drivers are managed by kernel itself. Modules works here as device drivers. Modules can interact with kernels directly. When we write device drivers, we use the module structure to specify custom routines. (I have posted the basic module structure before, you can take a look on that).

To load the driver we use module_init and to unload we use module_exit. When the module_init is executed, the first routine is executed as well. We have seen this example when we wrote the elementary module on previous post. The kernel registers the driver by using a registration routine
register_chrdev while loading the module and when unloading the module it uses unregister_chrdev. By the way, these are for character devices. I still don't know what actually these does, I'll find it out later.

Naming Devices

In linux, devices are labeled by numbers (0-255). These 256 numbers are known as major numbers. A major number is assigned to a particular device. So, Linux can handle 256 devices all together. Only 256 devices? No, they are major devices. Each major device can handle additional 256 devices of that type. Lets recalculate the number 256x256 = 65535. Well, now nobody can call this a small number. kernels documentation/devices.txt file is supposed to have the list of all major devices. I'll upload that file once I boot into ubuntu (Now I'm on Vista). By the way, the 0-th device is known as null device.

Applications can not access the device by the major number directly. Rather, apps use something called file system entries. I guess I didn't mention it earlier. The beauty of linux is, it can treat all physical devices, virtual devices and real file systems as file systems. The benefit of this is we can use the generic structure for all of them, without knowing what type of device we are using, still it is not that easy as it sounds right now. All driver entry points are located on a directory "/dev". For example, /dev/tty1 is the serial port 1 [COM1] . Applications which want to use any driver uses a system call to get the handle of the device. Once it gets the handle, it can gain access of the devices and can use the device by other system calls.


Driver Installation

Driver Installation is varied by linux distribution. As I have mentioned earlier. Linux uses modules as device drivers. All drivers are installed as modules and are located in directory "/lib/modules/kernel_x.x.xx". A configuration file located on /etc/modules.conf is used by the kernel [and user if you want to override it] to load and unload the modules. Module installing and uninstalling can be done by kernel module utilities like insmod, rmmod [we have used it on previous examples] and modprobe. Installing/inserting a module isn't everything, the module has to be registered as a device entry in the directory "/dev". The utility mknod does this job.

To see what drivers have been installed, we can see the contents of "/proc/module". Which will show the list of all loaded modules/devices.

A little break and back to business

Last week was midterm week. In addition I got fever on the weekend. So couldn't do much things on my research. Now I am back on my mission.

Now I know how a basic Linux driver works, I was wondering how a Microsoft Windows Driver works. Well, I tried to study MS driver stuff before, but it seemed Hebrew to me. Now I could understand most of the things as I know linux stuff better. Thanks to a thesis paper DOWNLOAD called "A Comparison of the Linux and Windows Device Driver Architectures" by Melekam Tsegaye and Richard Foss [Rhodes University, South Africa]. I was looking for something exactly like this. This paper answered too many things I was looking for. If I want to give you the summary, I have to copy and paste the whole document. The document is concise and each and every word is descriptive.

I'll do what I was doing. I'll post later was useful for me.

My supervisor [Dr. Mumit Khan] gave me a couple of links yesterday. The site was down for maintenance. Now it is working, I'm going through those as well.

My next post will be based on another review over linux device drivers.

Tuesday, June 26, 2007

3 more features for a basic module

Just learned few things which are useful.

1. Licensing and Documentation
2. Passing Arguments to a module and
3. Writing a driver on more than one file.

I am still working on it. All are tested though, I am experimenting them on different situations.
I'll be posting sample codes and outputs soon.

Here's a sample module info of the modified hello.c

filename: hello.ko
description: A sample driver
author: Raihan Hasnain
license: GPL
srcversion: 76F9BD32BB1DECDFF563E8E
depends:
vermagic: 2.6.20-16-generic SMP mod_unload 586



Friday, June 22, 2007

3. Simulate a Device Driver

Now I have to simulate a device driver.

The easiest simulation is to insert a test module into kernel (which essentially does nothing) then removing it from the kernel.

We ca use this hello.c source file to make a module

#include <linux/module.h>
#include <linux/kernel.h>

int init_module (void) /* Loads a module in the kernel */
{
printk(KERN_INFO "Hello kernel\n");
return 0;
}

void cleanup_module(void) /* Removes module from kernel */
{
printk(KERN_INFO "GoodBye Kernel\n");
}


(Somehow I knew that I need linux-headers linstalled in my linux to compile these sort of codes. )
I tried to compile it for the first time

gizmo@ububtu:~/mod$ gcc -c hello.c
hello.c:1:26: error: linux/module.h: No such file or directory
hello.c: In function ‘init_module’:
hello.c:6: error: ‘KERN_INFO’ undeclared (first use in this function)
hello.c:6: error: (Each undeclared identifier is reported only once
hello.c:6: error: for each function it appears in.)
hello.c:6: error: expected ‘)’ before string constant
hello.c: In function ‘cleanup_module’:
hello.c:12: error: ‘KERN_INFO’ undeclared (first use in this function)
hello.c:12: error: expected ‘)’ before string constant

See the red line. There is an error. I tried to find if there is any module.h is in my include directory.
I always knew that when a header file is included, compiler searches /usr/src/linux-headers-2.x.xx-xx/ directory and attached the header (*.h) file/files.

So I searched the /usr/src/linux-headers-2.6.20-16-generic/include/linux folder (2.6.20-16-generic is my kernel version) and I found module.h. Well I was wrong.

I went to my advisor and he let me know some secrets of GCC which I never knew and still can't find them by Google.

One of them is compiling on verbose mode, by adding -v parameter. Which gives line by line logging when compiling. And another is -save-temps parameter, which saves the intermediate file *.i and some other intermediate files. *.i file is a concatenated file of the header files and the source file (*.c/*.cc/*.cpp).

Let's see what happened to my module code in verbose mode.

gizmo@ububtu:~/mod$ gcc -c hello.c -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
/usr/lib/gcc/i486-linux-gnu/4.1.2/cc1 -quiet -v hello.c -quiet -dumpbase hello.c -mtune=generic -auxbase hello -version -fstack-protector -fstack-protector -o /tmp/ccQ7Kn8b.s
ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../i486-linux-gnu/include"
ignoring nonexistent directory "/usr/include/i486-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/i486-linux-gnu/4.1.2/include
/usr/include
End of search list.
GNU C version 4.1.2 (Ubuntu 4.1.2-0ubuntu4) (i486-linux-gnu)
compiled by GNU C version 4.1.2 (Ubuntu 4.1.2-0ubuntu4).
GGC heuristics: --param ggc-min-expand=63 --param ggc-min-heapsize=63380
Compiler executable checksum: c0d954aeefbb96d795ff3f6b3b72ef51
hello.c:1:26: error: linux/module.h: No such file or directory
hello.c: In function ‘init_module’:
hello.c:6: error: ‘KERN_INFO’ undeclared (first use in this function)
hello.c:6: error: (Each undeclared identifier is reported only once
hello.c:6: error: for each function it appears in.)
hello.c:6: error: expected ‘)’ before string constant
hello.c: In function ‘cleanup_module’:
hello.c:12: error: ‘KERN_INFO’ undeclared (first use in this function)
hello.c:12: error: expected ‘)’ before string constant


Check out the red lines. I was wrong! GCC 4.1.2 never looks on /usr/src/linux-headers-2.6.20-16-generic/ directory. Now I need to know a way, which can tell GCC to look up on appropriate folder.

In my university lab where PCs are powered by Fedora Core 5, this module code compiled without any error! I use ubuntu fiestly fawn (7.04) at my home. I thought ubuntu has this problem with gcc. So I chosen a shortcut, which led me to a disaster.

This part is kind of an offtopic!
I consider last week as my disaster week. As I saw ubuntu is not doing good, I considered installing Debian 4.0. I took it from a senior student, well I had to take it twice! Both time my DVD's had faults when burning. Then I tried to install fedora core 6. By the way, my DVD-ROM drive was faulty, when I was in the middle of installing FC6, installation corrupted, and I ended up with a broken GRUB (boot loader). Finally, no boot loader to boot any OS, no DVD drive to install anything else. I had to waste a whole week because of this, then bought a new DVD drive and Fedora Core 7 DVD.

FC7 started a new era for Fedora Cores, as it has a community repository now. Which is now letting FC to be a general purpose OS for all. Why? It has no kernel-header installed, no ant installed, most of the dev packages are vanished and it has a nice looking interface!

Guess what ...


when I tried to compile this code again
gizmo@desktop:~/mod$ gcc -c hello.c
the output is ...
hello.c:2:26: error: linux/module.h: No such file or directory


Meanwhile I posted an important thread on www.ubuntuforums.org

You can visit this thread here http://ubuntuforums.org/showthread.php?t=474991

I decided to get back on ubuntu fiesty. Installed it again, updated it up to date. Installed the things I needed and now I'm back to business!

Moral: For developing purpose, DO use whatever you want to use or you were using. DO NOT change distros, it won't help you at all.

Thanks to
alexOoO for showing me a nice example of Makefile and the_unforgiven for giving me a superb link of "The Kernel Module Programming Guide". I am follwing this guide now, as the book I was following previously was for older kernels.

Now I just made a Makefile with these codes.

obj-m += hello.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Then I tried to compile with 'make' command, and the output is

gizmo@ububtu:~/mod$ make
make -C /lib/modules/2.6.20-16-generic/build M=/home/gizmo/mod modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.20-16-generic'
CC [M] /home/gizmo/mod/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/gizmo/mod/hello.mod.o
LD [M] /home/gizmo/mod/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.20-16-generic'

NICE! Let's just ignore the warning messages, I can fix that later. At least the module could be compiled by my distro. Lets see if the module information.

gizmo@ububtu:~/mod$ modinfo hello.ko
filename: hello.ko
srcversion: 4C36855B98BAF2C01D9C1E9
depends:
vermagic: 2.6.20-16-generic SMP mod_unload 586


Let's try to insert the module into kernel.
NOTE: Inserting/Removing needs root/superuser permission.

gizmo@ububtu:~/mod$ sudo insmod ./hello.ko

Compiler doesn't show any error, so the module is inserted.
The code was supposed to print "Hello Kernel" on the log when the module is inserted. Let's check out the log if the message is printed.

gizmo@ububtu:~/mod$ cat /var/log/messages
...
...
Jun 22 14:05:20 ububtu -- MARK --
Jun 22 14:08:54 ububtu kernel: [ 6237.218196] hello: module license 'unspecified' taints kernel.
Jun 22 14:25:21 ububtu -- MARK --
Jun 22 14:32:42 ububtu kernel: [ 7662.119510] Hello kernel

Now let's try to remove the module
gizmo@ububtu:~/mod$ sudo rmmod ./hello.ko

and the log file says ...

gizmo@ububtu:~/mod$ cat /var/log/messages
...
...
Jun 22 14:05:20 ububtu -- MARK --
Jun 22 14:08:54 ububtu kernel: [ 6237.218196] hello: module license 'unspecified' taints kernel.
Jun 22 14:25:21 ububtu -- MARK --
Jun 22 14:32:42 ububtu kernel: [ 7662.119510] Hello kernel
Jun 22 14:34:24 ububtu kernel: [ 7764.009453] GoodBye Kernel

Done!

It was the simplest module than can be inserted. Next time I'll try to understand the module structure in more depth and how to work on module licenses.

Now I have to do compiler assignment PA2, I have wasted too much time looking for distros. Wish me luck.

2. Structure of Kernel Module

Kernel modules can be developed for two types of devices.

Block Devices

As the name says, Kernel accesses block devices by blocks (usually 1kb). It is generally used for hosting file systems.

Character Devices
Kernel accesses char devices like a file. Parallel port, Serial ports are char devices.

Kernel modules can be loaded or unloaded into kernel dynamically in runtime. So kernel module has a generic structure*.

struct module
{
unsigned long size_of_struct;
struct module *next;
const char *name;
unsigned long size;
long usecount;
unsigned long flags;
unsigned int nsyms;
unsigned int ndeps;
struct module_symbol *syms;
struct module_ref *deps;
struct module_ref *refs;
int (*init)(void);
void (*cleanup)(void);
const struct exception_table_entry *ex_table_start;
const struct exception_table_entry *ex_table_end;
#ifdef __alpha__
unsigned long gp;
#endif
};


Return Values

On success, zero is returned. On error, -1 is returned
and errno is set appropriately.


I still don't know how this structure works. I only know about two methods (marked blue). First one initializes a module to be inserted, second one does the job of removing.

I'll study abouth the other methods eventually.

*courtesy: module structure, http://www.freeos.com/articles/2677/

1. What is Device Driver?

In short, device driver is a software program which talks to the computer and controls the device. If you really want a bookish definition, you better check this site CLICK HERE. I'd rather post a simple definition which makes sense.

NOTE: From next time, whenever you see me mentioning 'drivers' or 'dd', consider it as device drivers.

Before getting into device drivers, I should mention that OS has a vital role here. One of the most important features of OS is resource management, which includes I/O operation with devices. Devices are connected with I/O ports. Interfacing does the physical connection, OS can send the requests to the device. Here comes the role of drivers. Driver is the OS of the device itself, it can talk to the computers OS and thus computers OS recognizes the device. Later drivers can control the device, which is essentially the I/O instructions by the computers OS.


Lets narrow down a bit more. OS is a huge entity to consider. By OS here we mean the kernel of an OS. Kernel is the core of the OS. Drivers has to either be inside the kernel to recognize devices or has to be somewhere near the kernel so that it can easily communicate with the kernel.

Check out the diagram*.



So here comes the kernel. I just mentioned that the driver can be inside the kernel, that is known as monolithic kernel, which actually has to come with the kernel package. There is another way of implementing drivers, that is by kernel modules.

My concern is now with kernel modules only.

Kernel modules are pieces of codes. Which can be loaded and unloaded upon demand. Letting us not worry about rebuilding the kernel again and again.

On my next post, I'll show the structure of the kernel module.


*Image courtesy: http://www.linuxjournal.com/article/2476

Thursday, June 21, 2007

Summary of Week 1-2

Before I could start anything, I grabbed this book (Linux Device Drivers, by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman) as my reference. There is not many books available on the market. So, this book seemed to be blessing. More to add it has a web version to browse and pdf version to download for totally free.
http://lwn.net/Kernel/LDD3/


On first week, I was assigned to do 3 jobs
  1. Learn how device driver works
  2. Learn the 'structure' of device driver module
  3. Simulate a device driver
I will be posting separate threads for my 3 jobs as they are lengthy when describing.

Pre-thesis

I study Computer Science and Engineering (CSE) in BRAC University (www.bracuniversity.ac.bd). Now I am a level-4 student. We have to do a thesis to complete our graduation, before deciding what to do on the thesis we have to go through a pre-thesis. Which is very helpful for the thesis.

My pre-thesis is on Device Drivers and my advisor is Dr. Mumit Khan.

My initial approach is just to know what is device drivers and how does it work. As Linux gives the opportunity to play with these things. I am using Linux as my platform.

Intro [You can always skip this part!]

"I am a huge fan of Operating Systems" - I know it sounds odd. Most of my friends reacts like "Cool! ... but what is it?" or "OS? You mean Windows?". Well I am not going into that story, but I have used and seen a lot of OS's since 1992.

My first experience of OS was with DOS in 1992. I did not use it rather seen my uncle using it. Then my dad got his computer at office in 1994. I got introduced with Windows 3.1 ... which was a new experience for me. In 1997 my best friend got a computer with Windows 95, which actually let me know there are different windows. At last I got a PC of my own in mid 98, with windows 95 loaded. That was just the beginning. Later I have used Windows 98, 98se, ME. In year 2000, I got introduced with another OS, which was totally different - BeOS5. Then I got QNX. I learned that there are other things rather than windows. Rad Hat 6.0 was a break through. I never knew there was a substitute of Windows, but RH was a bit complicated. In 2004, I bought a new computer with better specification, I installed Fedora Core 3, and that seemed to be a lot better. In 2005, Ubuntu 5.04 was a complete breakthrough for me. I used to start using linux beside windows XP. Then Ubuntu 6.06 was enough to convince me I do not need windows anymore. Meanwhile I tried Fedora Core 5,6,7, Mandriva 2007 and openSuSe 10.1. All are good, specially for general users. But in this year Ubuntu Fiesty Fawn 7.04 let me use quit windows completely. I play games, I compose musics, I watch DVDs, I use MSN messenger, I transfer songs into iPod, I use bluetooth to transfer stuffs from my cellphone. Everything is nice - without crashes, scan disks and blue screens of panic. Windows Vista seemed to be a lot better than the previous versions, but it is most resource hunger OS in the universe. Finally, I always tried to use Mac OSX. But I don't have a mac. Just a little information ... I use a MacOSX transformation pack on windows, which made my windows look like MacOSX, including the command prompt.

As a Computer Science and Engineering student. I always wanted to do something with Operating Systems. I have no intention to develop an OS from scratch, which is useless unless I make a open source MacOSX substitute for x86. I rather chosen an important sector of OS which made OS's this much usability. Yes, that is Device Drivers.

P.S.: I have earned an 'A' on my OS course! :D