内核list_head链表节点使用

硬件设备:JZ2440开发板

软件环境:Ubuntu15.04

自制编译器

 

本案例测试内核模块,实现链表的创建、增加节点、遍历和删除操作。

实现步骤:通过vim编写c源程序

  1. 编写相应的Makefile文件
  2. 在listdemo,c文件目录下执行make指令,生成ko文件
  3. 将生成的ko拷贝到开发板内
  4. 打开开发板,在ko文件目录下执行insmod listdemo.ko

listdemo.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
 
#include <linux/list.h>
 
MODULE_LICENSE("Dual BSD/GPL");
 
#define	EMPLOYEE_NUMBEROF 5
 
static struct list_head employee_list;
 
struct employee{
  char name[20];
  int number;
  int salary;
  struct list_head list;
};
 
static struct employee *employeep = NULL;
static struct employee *employeep_tmp = NULL;
static struct list_head *pos = NULL;
static struct list_head *pos1 = NULL;
 
static int __init listdemo_init(void)
{
  int i;
  printk(
 
KERN_ALERT "Entry listdemo_init!\n");
  INIT_LIST_HEAD(&employee_list);
  employeep = kmalloc(sizeof(struct employee) * EMPLOYEE_NUMBEROF,GFP_KERNEL);
  if(NULL==employeep){
    printk(KERN_ALERT "can't allocate memory for employee array from kernel!\n");
    return -ENOMEM;
  }
  printk(KERN_ALERT "Success to allocate memory for employee array from kernel!\n");
  memset(employeep,0,sizeof(struct employee) * EMPLOYEE_NUMBEROF);
 
  for(i=0;i<EMPLOYEE_NUMBEROF;i++){
    sprintf(employeep[i].name,"Employee%d",i+1);
    employeep[i].number = 1001 + i;
    employeep[i].salary = 50000 + 5000 * i;
    list_add(&(employeep[i].list),&employee_list);
  }
  list_for_each(pos,&employee_list){
    employeep_tmp = list_entry(pos,struct employee,list);
    printk(KERN_ALERT "Employee Name: %s\tNumber:%d\tSalary:%d!\n",employeep_tmp->name,employeep_tmp->number,employeep_tmp->salary);
  }
  return 0;
 
}
 
static void __exit listdemo_exit(void)
{
  printk(KERN_ALERT "Entry listdem_exit!\n");
  #if 0
    for(i=0;i<EMPLOYEE_NUMBEROF;i++){
      list_del(&(employeep[i].list));
    }
  #endif
    list_for_each_safe(pos,pos1,&employee_list){
      employeep_tmp = list_entry(pos,struct employee,list);
      list_del(&employeep_tmp->list);
    }
 
  printk(KERN_ALERT "Exit listdemo_exit!\n");
 
  kfree(employeep);
}
 
module_init(listdemo_init);
module_exit(listdemo_exit);
 
MODULE_AUTHOR("shenchao");
MODULE_DESCRIPTION("Demo kernel list_head");
MODULE_VERSION("0.0.1");
MODULE_ALIAS("ListSemo");

Makefile文件

KERN_DIR = /work/system/linux-3.14.11                                
 
all:
    make -C $(KERN_DIR) M=`pwd` modules 
 
clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order
 
obj-m   += listdemo.o

最终实现insmod listdemo.ko指令后输出:

/work # insmod listdemo.ko 
Entry listdemo_init!
Success to allocate memory for employee array from kernel!
Employee Name: Employee5        Number:1005     Salary:70000!
Employee Name: Employee4        Number:1004     Salary:65000!
Employee Name: Employee3        Number:1003     Salary:60000!
Employee Name: Employee2        Number:1002     Salary:55000!
Employee Name: Employee1        Number:1001     Salary:50000!

执行rmmod listdemo指令后输出:

/work # rmmod listdemo
Entry listdem_exit!
Exit listdemo_exit!

 

内核list_head链表节点使用

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

14 − 11 =

滚动到顶部
沪ICP备18028346号