Sunday, September 28, 2014

Writing portable Linux driver with respect to processor endianness


In my previous post I discussed about the Endianness concept.

There are many points to take care while writing a portable linux driver.One of the key point I wanted to mention here is the usage of some portable API's which will take care of the automatic endianness conversion for ensuring a portable driver.

Many times during kernel programming we interact with hardware devices for exchanging bytes of data.It can be the case that we receive data from hardware, we pack them and copy to application buffer and vice-versa.

Suppose I consider the case where I read some chunks of data from hardware and I need to copy the data to application buffer.I do not know that if its a little endian or a big endian processor where my driver is running and I only know that my application wants data in big endian format.

So if my driver was running on a little endian processor and I directly copy data to application buffer then it wrong.

So I use a API provided by linux kernel: cpu_to_be32()

Now this API takes as argument a 32-bit data and returns me the big endian format 32-bit data and therefore now I am happy, not to care about the native endianness.

Please have a look at some more API's in the below link and enjoy writing a portable linux driver:

Please have a look for such API's in below link:
http://lxr.free-electrons.com/source/include/linux/byteorder/generic.h

Determining Endianness of Native Processor


We generally encounter a very common term 'Endianness' while working in embedded programming.

Basically endianness is the way a machine architecture stores the data in the memory.We have two types of endianness - Little Endian and Big Endian.

In Little Endian architecture, lower byte data (LSB) is stored in lower address.
In Big Endian architecture, higher byte data (MSB) is stored in lower address.

Though various optimized and non optimized methods are available on internet, I have one more way of determining endianness of native processor.I guess it is one more non optimized method but yeah it is one method.

C code for determining endianness:

//This program determines the Endianness of Native Processor
#include <stdio.h>
void main()
{
int val1 = 256;
char val2 = 0;
val2 = (char*)val1;
if(0 == val2)
    printf("Native processor in Little Endian\n");
else
    printf("Native processor in Big Endian\n");
}

Please ignore warnings during compilation.GNU will give warnings because of non compatible typecasting.

Sunday, August 3, 2014

Getting information on current I/O scheduling policy for a block device

The kernel block layer gets the block I/O requests from the user for the disk access.The kernel does not issue block I/O requests to the disk in the order they are received or as soon as they are received. Instead, it performs operations called merging and sorting to greatly improve the performance of the system as a whole. The subsystem of the kernel that performs these operations is called the I/O scheduler.

Kernel mainly uses below scheduling policies for disk access:
1. Complete Fair Queuing (CFQ) 
2. Anticipatory
3. Noop
4. Deadline

Now suppose I want to get information about the current scheduling policy for one of my block device say CDROM.

As we know CDROM is represent in Linux as sr0 (can be sr1, sr2 etc. depending upon the number of same device type connected at that moment) node under /device directory.

So let me check what I/O scheduler is in for my CDROM.

a-saurabh@a-saurabh:~$ cat /sys/block/sr0/queue/scheduler 
noop deadline [cfq] 

The bracket one tells the current I/O scheduling policy.

I can though change my current scheduling policy:

a-saurabh@a-saurabh:~$ echo deadline > /sys/block/sr0/queue/scheduler
bash: /sys/block/sr0/queue/scheduler: Permission denied

Oh, I need to be a super user to do that.

a-saurabh@a-saurabh:~$ sudo su


root@a-saurabh:/home/a-saurabh# echo deadline > /sys/block/sr0/queue/scheduler


root@a-saurabh:/home/a-saurabh# cat /sys/block/sr0/queue/scheduler
noop [deadline] cfq 


So current I/O scheduling policy for my CDROM device has become deadline now.


References:


Sunday, June 8, 2014

Bash Script to determine capacity of a SCSI device


Please use above script to determine the capacity or device size of your SCSI device like Hard Disk (sda) or CD-ROM (sr0).
Copy the script into a script file e.g readcap.sh and run as below:

./readcap /dev/sda

Above command determines capacity of Hard Disk.

Script:

#This script display the SCSI device capacity you are quering about !!
#e.g. usage: ./readcap /dev/sda
#!/bin/bash
ls $1 2>/dev/null 1>/dev/null
if [ $(echo $?) -eq 0 ]
then
sudo sg_readcap  $1 | tail -1 | awk 'BEGIN{ORS ="";print "SCSI Device Capacity: "}{print $7;ORS="\n"}END{print " GB"}'
else
echo "Wrong SCSI device entered/Incorrect usage of script"
fi

Guys please report me back any issues found during script execution.

Tuesday, June 3, 2014

Querying SCSI devices

Sometimes we want to query about our devices present in our computer. e.g. Hard Disks , DVD drives etc.These devices comes into the family of SCSI (Small Computer Systems Interface) devices.So we can use some of the SCSI commands to query the status of the SCSI devices.I use linux system to demonstrate this.

First installation of sg3-utils package is required.You can get more information on sg3-utils package by clicking on below link:

http://sg.danny.cz/sg/sg3_utils.html

So first step is to install sg3-utils package using command: sudo apt-get install sg3-utils

E.g. a-saurabh@a-saurabh:~$ sudo apt-get install sg3-utils

Now once the package is installed , we get access to numerous and helpful utilities which makes possible to send SCSI commands from terminal to SCSI devices.

Suppose I want to see serial number of my hard disk, I can issue the below command.

a-saurabh@a-saurabh:~$ sudo sg_inq -p 0x80 /dev/sda
VPD INQUIRY: Unit serial number page
  Unit serial number:      WD-WMC2E7086390

Basically we have send an SCSI INQUIRY command with page code 0x80 (Representing Unit Serial Number) to our hard disk node under /dev directory.

We can also list the supported pages by the SCSI device by sending the command:

a-saurabh@a-saurabh:~$ sudo sg_inq -p 0x00 /dev/sda
 Only hex output supported. sg_vpd decodes more pages.
VPD INQUIRY, page code=0x00:
   [PQual=0  Peripheral device type: disk]
   Supported VPD pages:
     0x0 Supported VPD pages
     0x80 Unit serial number
     0x83 Device identification
     0x89 ATA information
     0xb0 Block limits (sbc2)
     0xb1 Block device characteristics (sbc3)
     0xb2 Logical block provisioning (sbc3)


Here we query about the supported inquiry pages by the device.

We use -p option in the sg_inq command for specifying the page which is being queried,

Likewise we can request information for more inquiry pages from SCSI devices.

Tuesday, May 20, 2014

Shell Script for reading a file line by line

Below script reads an input file line by line and displays each line with a half a second delay:

#Please provide file to be read as input while executing script
#!/bin/bash
count=$(cat $1 | wc -l)
for (( i=1; i<=$count; i++ ))
do
value=$(cat $1 | head -$i | tail -1)
echo $value
sleep 0.5
done

Above script reads each line and stores the same in value variable and henceforth value can be utilized for many other manipulations.

There are many other standard methods of reading a file specially with read line in while loop but I had prepared my own method to read the file. :)

Thursday, April 17, 2014

Removing CamelCase warnings in code given by checkpatch.pl

Before pushing you kernel code to GIT you need to make the code error and warning free.There are some standard scripts in linux kernel repository to point out the errors and warnings.One of them is checkpatch.pl script.

My shell scripts will try to clean some of these pointed error and warnings.

Here's my first script to remove CamelCase from kernel code.

Please refer to the link for details on CamelCase: http://en.wikipedia.org/wiki/CamelCase

Shell Script for removing CamelCase from code:

#!/bin/bash
#Here, arg#1 is string whose CamelCase needs to be removed.
#arg2 is the file in which CamelCase needs to be removed.
var1=$1
var2=$(echo $var1 | tr [:upper:] [:lower:])
sed -i "s/\<$var1\>/$var2/g" $2

Above scripts actually converts the CamelCases in your file to lower cases so you will not get any warning now with checkpatch.pl