C 中的内存管理 - Linux 内核
Memory management in C - Linux Kernel
我正在尝试编写一个 Linux 内核模块,但我遇到了一个非常简单的问题。
我有一个指向内核提供的结构的指针,我只想将其中一个元素复制到局部变量。
当 运行 我的代码时,分配给变量的数据返回为 (null)。
我已经阅读了很多关于内存管理的帖子,但我仍然遗漏了一些东西。
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/list.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
struct usb_bus *bus;
size_t ret;
static char *get_usb_bus_serial(struct usb_bus *bus)
{
char *serial;
serial = kmalloc(sizeof(char) * 128, GFP_KERNEL);
strcpy(serial, bus->root_hub->serial);
return serial;
}
static int __init usb_fun_init (void)
{
int id;
int chix;
struct usb_device *dev, *childdev = NULL;
printk(KERN_INFO "\n************************************ in init\n");
mutex_lock(&usb_bus_idr_lock);
idr_for_each_entry(&usb_bus_idr, bus, id)
{
printk(KERN_INFO "***************** Begins ****************");
printk(KERN_INFO "Vendor ID = %x", bus->root_hub->descriptor.idVendor);
printk(KERN_INFO "Product ID = %x", bus->root_hub->descriptor.idProduct);
printk(KERN_INFO "Serial Number = %x", bus->root_hub->descriptor.iSerialNumber);
//printk(KERN_INFO "Manu = %s", bus->root_hub->descriptor.iManufacturer);
printk(KERN_INFO "Manu = %s", bus->root_hub->manufacturer);
printk(KERN_INFO "Product = %s", bus->root_hub->product);
printk(KERN_INFO "Serial Number = %s", bus->root_hub->serial);
printk(KERN_INFO "Serial Number = %s", get_usb_bus_serial(bus));
//printk(KERN_INFO "\nManufacturer = %s", udev.bus.iManufacturer); - error: request for member ‘iManufacturer’ in something not a structure or union
dev = bus->root_hub;
usb_hub_for_each_child(dev, chix, childdev)
{
if(childdev)
{
printk(KERN_INFO "***************** Child device ****************");
usb_lock_device(childdev);
printk(KERN_INFO "Vendor ID = %x", childdev->descriptor.idVendor);
printk(KERN_INFO "Product ID = %x", childdev->descriptor.idProduct);
printk(KERN_INFO "Serial Number = %x", childdev->descriptor.iSerialNumber);
printk(KERN_INFO "Manu = %s", childdev->manufacturer);
printk(KERN_INFO "Product = %s", childdev->product);
printk(KERN_INFO "Serial Number = %s", childdev->serial);
usb_unlock_device(childdev);
}
}
}
mutex_unlock(&usb_bus_idr_lock);
return 0;
}
static void __exit usb_fun_exit (void)
{
printk(KERN_INFO "\n************************************ in exit\n");
}
module_init(usb_fun_init);
module_exit(usb_fun_exit);
输出
Feb 29 06:54:25 ubuntu kernel: [ 5238.163373] Serial Number = (null)
编辑
修复注释中的问题后,插入模块时会发生空指针取消引用。我仍然对我到底做了什么导致这个问题感到困惑。
正如@ensc 指出的那样,应该使用 kmalloc() 而不是 vmalloc(),上面的代码运行并且 returns 正确的输出
Feb 29 07:31:31 ubuntu kernel: [ 725.618665] Serial Number = 0000:02:00.0
我正在尝试编写一个 Linux 内核模块,但我遇到了一个非常简单的问题。
我有一个指向内核提供的结构的指针,我只想将其中一个元素复制到局部变量。
当 运行 我的代码时,分配给变量的数据返回为 (null)。
我已经阅读了很多关于内存管理的帖子,但我仍然遗漏了一些东西。
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/list.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
struct usb_bus *bus;
size_t ret;
static char *get_usb_bus_serial(struct usb_bus *bus)
{
char *serial;
serial = kmalloc(sizeof(char) * 128, GFP_KERNEL);
strcpy(serial, bus->root_hub->serial);
return serial;
}
static int __init usb_fun_init (void)
{
int id;
int chix;
struct usb_device *dev, *childdev = NULL;
printk(KERN_INFO "\n************************************ in init\n");
mutex_lock(&usb_bus_idr_lock);
idr_for_each_entry(&usb_bus_idr, bus, id)
{
printk(KERN_INFO "***************** Begins ****************");
printk(KERN_INFO "Vendor ID = %x", bus->root_hub->descriptor.idVendor);
printk(KERN_INFO "Product ID = %x", bus->root_hub->descriptor.idProduct);
printk(KERN_INFO "Serial Number = %x", bus->root_hub->descriptor.iSerialNumber);
//printk(KERN_INFO "Manu = %s", bus->root_hub->descriptor.iManufacturer);
printk(KERN_INFO "Manu = %s", bus->root_hub->manufacturer);
printk(KERN_INFO "Product = %s", bus->root_hub->product);
printk(KERN_INFO "Serial Number = %s", bus->root_hub->serial);
printk(KERN_INFO "Serial Number = %s", get_usb_bus_serial(bus));
//printk(KERN_INFO "\nManufacturer = %s", udev.bus.iManufacturer); - error: request for member ‘iManufacturer’ in something not a structure or union
dev = bus->root_hub;
usb_hub_for_each_child(dev, chix, childdev)
{
if(childdev)
{
printk(KERN_INFO "***************** Child device ****************");
usb_lock_device(childdev);
printk(KERN_INFO "Vendor ID = %x", childdev->descriptor.idVendor);
printk(KERN_INFO "Product ID = %x", childdev->descriptor.idProduct);
printk(KERN_INFO "Serial Number = %x", childdev->descriptor.iSerialNumber);
printk(KERN_INFO "Manu = %s", childdev->manufacturer);
printk(KERN_INFO "Product = %s", childdev->product);
printk(KERN_INFO "Serial Number = %s", childdev->serial);
usb_unlock_device(childdev);
}
}
}
mutex_unlock(&usb_bus_idr_lock);
return 0;
}
static void __exit usb_fun_exit (void)
{
printk(KERN_INFO "\n************************************ in exit\n");
}
module_init(usb_fun_init);
module_exit(usb_fun_exit);
输出
Feb 29 06:54:25 ubuntu kernel: [ 5238.163373] Serial Number = (null)
编辑
修复注释中的问题后,插入模块时会发生空指针取消引用。我仍然对我到底做了什么导致这个问题感到困惑。
正如@ensc 指出的那样,应该使用 kmalloc() 而不是 vmalloc(),上面的代码运行并且 returns 正确的输出
Feb 29 07:31:31 ubuntu kernel: [ 725.618665] Serial Number = 0000:02:00.0