Penesive Random Experiments

Tracking linux next

I have been trying to get the latest version of the linux-next. As you guys already know all the latest changes of all the subsystem trees are pulled regularly into the linux-next tree and this helps in detecting merge conflicts earlier.I had already mentioned how I would clone the linux next tree in here.

Now i was trying to pull the latest change into the linux-tree using the following command

pradheep@PradheepVM:~/linux-next/linux-next$ git pull

However i would end up with loads of merge conflicts when pulling linux-next tree similar to the below

CONFLICT (content): Merge conflict in arch/alpha/include/uapi/asm/mman.h
Auto-merging arch/Kconfig
Auto-merging Next/merge.log
CONFLICT (add/add): Merge conflict in Next/merge.log
Auto-merging Next/Trees
CONFLICT (add/add): Merge conflict in Next/Trees
Auto-merging Next/SHA1s
CONFLICT (add/add): Merge conflict in Next/SHA1s
Auto-merging MAINTAINERS
Auto-merging Documentation/ioctl/ioctl-number.txt
Auto-merging Documentation/devicetree/bindings/drm/msm/hdmi.txt
CONFLICT (content): Merge conflict in Documentation/devicetree/bindings/drm/msm/hdmi.txt
Automatic merge failed; fix conflicts and then commit the result.

This is because the linux-next tree contains the merges with conflicts and hence when we pull the linux-next tree we get all the merge conflicts.

So how do we get the latest changes without trying to merge all the conflicts? One has to do the following to update linux-next

$ git checkout master   
...
$ git remote update 

Then we can list out the recent tags

pradheep@PradheepVM:~/linux-next/linux-next$ git tag -l next-* | tail
next-20150721
next-20150722
next-20150723
next-20150724
next-20150727
next-20150728
next-20150729
next-20150731
next-20150804
next-20150805

Then create the lastest linux-next branch by using the following command

pradheep@PradheepVM:~/linux-next/linux-next$ git checkout -b mynewbranch next-20150805
Switched to a new branch 'mynewbranch'

This branch has all the related changes of the merges that was performed recently.

I found most of these information from the kernel doc

Sending mails through git ends up in spam folder

Have you ever wondered why sending mails using git ends up in spam folder in your gmail mailbox. I was recently trying to send some patches of git to someone and i noticed that all the mails i sending using git-format0-mail ends up in my spam folder.

This was annoying and i wanted to make sure that it never happens again and so i digged ina bit.I was using my gmail account to send the mails using my account login and password.But still the mails ended up as spam.

This is because gmail is not able to make the channel secure using TLS/SSL autentication.The simple solution is to use a package called msmtp-mta.

You can install it by using

sudo apt-get install msmtp-mta

Now that you have installed tha package you need to configure it using the .msmtprc in your home directory

vi  ~/.msmtprc

Now you need to configure your account details by modifying the necessary fields.

   # Example for a user configuration file
   # Set default values for all following accounts.
   defaults
   tls on
   tls_trust_file  /etc/ssl/certs/ca-certificates.crt
   logfile ~/.msmtp.log
   # My email service
   account gmail
   host smtp.gmail.com
   port 587
   from your@accountdetails.com
   auth on
   user your@accountdetails.com
   password your@password
   # Set a default account
   account default : gmail

Now change the file permission so that no one can see it

chmod 600 .msmtprc

If you are using gmail, i strongly suggest you to use the 2 step autenticaion mechanisim as mentioned here.

This will make sure that you dont have to expose your gmail actual password and no other person can use it even if he sees it.

Now that you have all the mail configuration done you can use the git-format-patch as earlier without any changes as below


 git format-patch  -n2  --to=yourId@gmail.com 

Creating a simple sysfs module in linux kernel

Sysfs is the commonly used method to export system information from the kernel space to the user space for specific devices.THe procfs is used to export the process specific information and the debugfs is used to used for exporting the debug information by the developer.

The sysfs is tied to the device driver model of the kernel.To more about device driver model see [1]

So lets start building a simple sysfs that we will export to the user space.

the following is the basic structure of any simple device driver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <linux/module.h>
#include <linux/init.h>

static int __init mymodule_init (void)
{
        pr_debug("Module initialized successfully \n");
        return 0;
}

static void __exit mymodule_exit (void)
{
        pr_debug ("Module un initialized successfully \n");
}

module_init(mymodule_init);
module_exit(mymodule_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("pradheepsh");

At the heart of the sysfs model is the Kobject.Kobject is the glue that binds the sysfs and the kernel.

In this example lets write a simple code that will add a directory and a file to the sysfs.The file will allow reading and writing data to the sysfs of a fixed size of 4096 bytes.

The first step is to create a directory into the /sys/kernel directory. Thiscan be done by adding the following line in the mymodule_init function

1
2
3
4
example_kobject = kobject_create_and_add("kobject_example",
                                                 kernel_kobj);
if(!example_kobject)
    return -ENOMEM;

Dont forget to remove the kobject from the sysfs ,else the entry cannot be deleted untill the system is rebooted.

1
 kobject_put(example_kobject);

Now compile the kernel module and load it using insmod and you will see the following entry

pradheep@PradheepVM:$ ls /sys/kernel/
.. kobject_example  ..

The second step is creating the actual file attribute.There are loads of helper function that can be used to create the kobject attributes.They can be found in header file sysfs.h

To create a single file attribute we are going to use ‘sysfs_create_file’.One can use another function ‘ sysfs_create_group ‘ to create a group of attributes.

1
2
3
4
error = sysfs_create_file(example_kobject, &foo_attribute.attr);
if (error) {
 	pr_debug("failed to create the foo file in /sys/kernel/kobject_example \n");
} 

in the above code the second argument foo_attribute.attr helps in registering the callback methods that is needed to be used when the particular file example_kobject is accessed. It can be defined using the macro __ATTR as below

	static struct kobj_attribute foo_attribute =__ATTR(foo, 0660, foo_show,  foo_store);

what the above code essentially does is as set the corresponding attribute name, permission and the callback methods to be used when the file foo is accessed.

1
2
3
4
5
6
7
8
static struct device_attribute foo_attrute = {
	.attr = {
		.name = "foo",
		.mode = S_IWUSR | S_IRUGO,
	},
	.show = foo_show,
	.store = foo_store,
};

The third step is to use a define what needs to be done when the particular file/attribute foo is accessed. In this case we expect the user would allow user to write an integer value and when read we give back the integer value that was written earlier.

static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
                      char *buf)
{
        return sprintf(buf, "%d\n", foo);
}

static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr,
                      char *buf, size_t count)
{
        sscanf(buf, "%du", &foo);
        return count;
}

The full implementation is as follows

#include <linux/module.h>
#include <linux/printk.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/string.h>

static struct kobject *example_kobject;
static int foo;

static ssize_t foo_show(struct kobject *kobj, struct kobj_attribute *attr,
                      char *buf)
{
        return sprintf(buf, "%d\n", foo);
}

static ssize_t foo_store(struct kobject *kobj, struct kobj_attribute *attr,
                      char *buf, size_t count)
{
        sscanf(buf, "%du", &foo);
        return count;
}


static struct kobj_attribute foo_attribute =__ATTR(foo, 0660, foo_show,
                                                   foo_store);

static int __init mymodule_init (void)
{
        int error = 0;

        pr_debug("Module initialized successfully \n");

        example_kobject = kobject_create_and_add("kobject_example",
                                                 kernel_kobj);
        if(!example_kobject)
                return -ENOMEM;

        error = sysfs_create_file(example_kobject, &foo_attribute.attr);
        if (error) {
                pr_debug("failed to create the foo file in /sys/kernel/kobject_example \n");
        }

        return error;
}

static void __exit mymodule_exit (void)
{
        pr_debug ("Module un initialized successfully \n");
        kobject_put(example_kobject);
}

We can change the above code to store any value (upto 4096 bytes) by just changing the logic as follows.

###Links

  1. Device driver model of Linux.
  2. [Simple Makefile for Linux kernel] ()
  3. [Good overview of Kobject] (http://lwn.net/Articles/51437/)