Monday, 19 March 2012

Linux: How kernel talk to devices

Inside the kernel are functions for each of the devices the kernel is going to access. All the routines for a specific device are jointly referred to as the Device driver. Each device on the system has its own device driver. Eg: for devices such as a hard disk or terminal, the system needs to be able to open the device, write to the device, read from the device, and close the device, therefore, the respective drivers will contain the routines needed ..

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 and this special information is accomplished by Major and Minor numbers.

The major device numbers are used to distinguish between different devices and their controllers.The major number is actually the offset into the kernel's device driver table, which tells the kernel what kind of device it is.

The minor number tells the kernel special characteristics of the device to be accessed.

It is through this table that the routines are accessed that, in turn, access the physical hardware. Once the kernel has determined what kind of device to which it is talking, it determines the specific device, the specific location, or other characteristics of the device by means of the minor number.

The major number for the sd (SATA) driver is hard-coded at 8.  The minor numbers have the format
(<unit>*16)+<part>) where,

unit- SATA drive number on the first controller either 0 or 1. so all sd devices has minor number less than 16.
part- Partition number, which can be anything from 1 to 20.

Which minor numbers you will be able to access will depend on how many partitions you have and what kind they are (extended, logical, etc.). The minor number of the device node that represents the whole disk is 0. This has the node name sda, whereas the other device nodes have a name equal to their minor number (/dev/sda2 has a minor number 2)

root@slackware:/dev]#fdisk -l

Disk /dev/sda: 48.1 GB, 48181477376 bytes
255 heads, 63 sectors/track, 5857 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x20d0a085

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1        1824    14651248+  83  Linux
/dev/sda2            1825        5857    32395072+   5  Extended
/dev/sda5            1825        5654    30764443+  83  Linux
/dev/sda6            5655        5857     1630566   82  Linux swap

From above we can conclude that :-

1. /dev/sda is the first controller and it's unit=0
2. Disk partitions are /dev/sda1, /dev/sda2, /dev/sda5, /dev/sda6.

Minor numbers are calculated as per formula -
(<unit>*16)+<part>):Substituting above we get,
(0*16)+0=0
(0*16)+1=1
(0*16)+2=2
(0*16)+5=5
(0*16)+6=6

In-case of another controller(unit=1), you would have minor numbers > 16.

root@slackware:/dev]#pwd
/dev

root@slackware:/dev]#ls -l sda*
brw-rw---- 1 root disk 8, 0 2012-03-19 13:06 sda
brw-rw---- 1 root disk 8, 1 2012-03-19 13:06 sda1
brw-rw---- 1 root disk 8, 2 2012-03-19 13:06 sda2
brw-rw---- 1 root disk 8, 5 2012-03-19 13:06 sda5
brw-rw---- 1 root disk 8, 6 2012-03-19 13:06 sda6

you could calculate Major and Minor according to the device info (Char/Block).

root@slackware:~]#cat /proc/devices
Character devices:
  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  6 lp
  7 vcs
  9 st
 10 misc
 13 input
 14 sound
 21 sg
 29 fb
 89 i2c
 99 ppdev
116 alsa
128 ptm
136 pts
171 ieee1394
180 usb
189 usb_device
245 pcmcia
246 rtc
247 hidraw
248 usb_endpoint
249 usbmon
250 gdth
251 megaraid_sas_ioctl
252 megadev_legacy
253 aac
254 bsg

Block devices:
  1 ramdisk
  3 ide0
259 blkext
  7 loop
  8 sd
  9 md
 11 sr
 22 ide1
 65 sd
 66 sd
 67 sd
 68 sd
 69 sd
 70 sd
 71 sd
 80 i2o_block
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
253 device-mapper
254 mdp

More information on "Devices" could be found in the below path.

root@slackware:~]#ls -l /usr/src/linux/Documentation/devices.txt
-rw-r--r-- 1 root root 118525 2009-07-02 23:41 /usr/src/linux/Documentation/devices.txt