Linux kernel link list instance

I will focus on the code implementation to give a detail description. If you like, enjoy it.

#include <linux/module.h>
#include <linux/list.h>
#include <linux/err.h>
#include <linux/slab.h>
/* Create a link list head, its name is container_measurement */
LIST_HEAD(container_measurement);
/* The main data structure that you define to construct a link list */
struct container_entry{
	int container_id;
	int status;
	struct list_head later;

};
/*Create the link list node and add it to the previous link list by "LIST_HEAD()"*/
static struct container_entry *container_entry_create(int container_id, int status)
{
	struct container_entry *entry;
	entry = kmalloc(sizeof(*entry),GFP_KERNEL);
	if(entry == NULL){
		pr_err("OUT OF MEMORY ERROR creating container_entry\n");
		return -ENOMEM;
	}
	entry->container_id = container_id;
	entry->status = status;
	INIT_LIST_HEAD(&entry->later);
	list_add(&entry->later,&container_measurement);
	return entry;
}
/*Lookup every link list node and find the node you want*/
static struct container_entry *container_entry_lookup(int container_id)
{
	struct container_entry *entry_p;
#if 0
	list_for_each(p, &container_measurement){
		entry_p = list_entry(p, struct container_entry,later);
		printk("Current: container_id:%d,status:%d\n", entry_p->container_id, entry_p->status);
	}
#endif
	list_for_each_entry(entry_p, &container_measurement,later){
		printk("Current: container_id:%d,status:%d\n", entry_p->container_id, entry_p->status);
		if( entry_p->container_id == container_id ){
			printk("Success: %d:status:%d\n", entry_p->container_id, entry_p->status);
			return entry_p;
		}
	}
        return NULL;


}
/*Remove the node by its single value*/
int container_entry_del(int container_id)
{
	struct container_entry *entry_p;
	
	entry_p = container_entry_lookup(container_id);
	if(entry_p == NULL){
		printk("There is no container_id: %d\n", container_id);
		return -1;
	}
	list_del(&entry_p->later);
	kfree(entry_p);
	return 0;

}
/*kernel module init*/
static int __init hello_init(void)
{
	struct container_entry *entry;
	int id;
	id = 200;
	
	entry = container_entry_create(100,0);
	entry = container_entry_create(200,1);
	container_entry_del(200);
	if ( container_entry_lookup(200) == NULL){

		printk("Sorry, container:%d does exist\n", id);
	}
	pr_info("hello\n");
	return 0;

}
/*kernel module exit*/
static void __exit hello_exit(void)
{
	printk("hello,I am leaving\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("sam");

The use of kgdb

Environment:

machine 0(target):

sam@sam-VirtualBox:~$ uname -a
Linux sam-VirtualBox 4.8.17 #2 SMP Wed Jun 21 07:51:10 CST 2017 x86_64 x86_64 x86_64 GNU/Linux
sam@sam-VirtualBox:~$ cat /etc/os-release
NAME=”Ubuntu”
VERSION=”16.04.2 LTS (Xenial Xerus)”
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME=”Ubuntu 16.04.2 LTS”
VERSION_ID=”16.04″
HOME_URL=”http://www.ubuntu.com/&#8221;
SUPPORT_URL=”http://help.ubuntu.com/&#8221;
BUG_REPORT_URL=”http://bugs.launchpad.net/ubuntu/&#8221;
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

sam@sam-VirtualBox:~$ uname -a
Linux sam-VirtualBox 4.8.17 #2 SMP Wed Jun 21 07:51:10 CST 2017 x86_64 x86_64 x86_64 GNU/Linux

You should add a serial port by vmware or virtualbox,like this: 

 

0

And now, you should modify the kernel command line(kgdboc,kgdbwait,kgdbcon), like this:

sam@sam-VirtualBox:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.8.17 root=UUID=d7708b30-87c5-48cf-a665-676abb621887 ro ima_tcb kgdboc=ttyS0,115200 kgdbwait kgdbcon quiet splash

 

machine1(host: running gdb)

sam@sam-VirtualBox:~$ uname -a
Linux sam-VirtualBox 4.8.17 #2 SMP Wed Jun 21 07:51:10 CST 2017 x86_64 x86_64 x86_64 GNU/Linux
sam@sam-VirtualBox:~$ cat /etc/os-release
NAME=”Ubuntu”
VERSION=”16.04.2 LTS (Xenial Xerus)”
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME=”Ubuntu 16.04.2 LTS”
VERSION_ID=”16.04″
HOME_URL=”http://www.ubuntu.com/&#8221;
SUPPORT_URL=”http://help.ubuntu.com/&#8221;
BUG_REPORT_URL=”http://bugs.launchpad.net/ubuntu/&#8221;
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

sam@sam-VirtualBox:~$ uname -a
Linux sam-VirtualBox 4.8.17 #2 SMP Wed Jun 21 07:51:10 CST 2017 x86_64 x86_64 x86_64 GNU/Linux

Also, you should enable the serial port for host machine.

1

Now, you should start the target machine, it will like below. It means that it is waiting for the remote debug.

3

So in you host machine,  you should run the gdb remote command to start the target machine.

4

Next should run “continue” , and the host machine will start.

5

 

6

Here we go.