2015-12-03 12:06:52 alex_mianmian 阅读数 2336
  • python全栈开发devops方向初到

    课程包含前端后端由浅入深,所有的课程全程以项目开发为主线进行讲解,作业题紧跟项目开发,让大家学完后,能够迅速巩固,大大降低了大学学习语法的时间。课程内容耗时一年精心准备,经过精编,单节课课时一般在15-30分钟。 包含项目:一共4个项目(用户系统 cmdb ansible任务管理系统 项目发布系统),并包含源码。

    3808 人正在学习 去看看 李哲

Linux 下PCI驱动架构是Linux BUS,DEVICE,DRIVER架构。下面所有代码来自linux3.13.

struct pci_dev 是描述device的数据结构。

struct pci_driver是描述driver的数据结构。

struct pci_bus是描述bus的数据结构。

device和driver都是挂 bus上的。


PCI 的 driver和device要做匹配验证的时候,验证的是vendor,id,class信息。

static inline const struct pci_device_id * pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
{
	if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
	    (id->device == PCI_ANY_ID || id->device == dev->device) &&
	    (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
	    (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
	    !((id->class ^ dev->class) & id->class_mask))
		return id;
	return NULL;
}

这个函数就是pci device和driver匹配的最底层函数。可以看到比较的是vendor,id,class信息。它的调用路径是:

pci_bus_match()->pci_match_device()->pci_match_one_device()


很多人介绍了pci driver该怎么写。但忽略了pci device何时被创建。

当一个pci driver注册到系统时,系统会去匹配pci driver和pci device。但这时其实pci device 已经被创建了,所以才能match。那pci device是在什么时候创建的呢?

答案是系统初始化时。

系统初始化时,会扫描pci总线,发现所有已经连在上面的设备,并为每个社保创建一个struct pci_dev对象。

struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
		struct pci_ops *ops, void *sysdata, struct list_head *resources)
{
	struct pci_host_bridge_window *window;
	bool found = false;
	struct pci_bus *b;
	int max;

	list_for_each_entry(window, resources, list)
		if (window->res->flags & IORESOURCE_BUS) {
			found = true;
			break;
		}

	b = pci_create_root_bus(parent, bus, ops, sysdata, resources); // 创建pci bus
	if (!b)
		return NULL;

	if (!found) {
		dev_info(&b->dev,
		 "No busn resource found for root bus, will use [bus %02x-ff]\n",
			bus);
		pci_bus_insert_busn_res(b, bus, 255);
	}

	max = pci_scan_child_bus(b);<span style="white-space:pre">	//扫描pci bus,找到pci设备

	if (!found)
		pci_bus_update_busn_res_end(b, max);

	pci_bus_add_devices(b);
	return b;
}
从pci bus的根开始扫描。

unsigned int pci_scan_child_bus(struct pci_bus *bus)
{
	unsigned int devfn, pass, max = bus->busn_res.start;
	struct pci_dev *dev;

	dev_dbg(&bus->dev, "scanning bus\n");

	/* Go find them, Rover! */
	for (devfn = 0; devfn < 0x100; devfn += 8)
		pci_scan_slot(bus, devfn);<span style="white-space:pre">	//扫描slot

        .
        .
        .
	return max;
}
接着看pci_scan_slot()
int pci_scan_slot(struct pci_bus *bus, int devfn)
{
	unsigned fn, nr = 0;
	struct pci_dev *dev;

	if (only_one_child(bus) && (devfn > 0))
		return 0; /* Already scanned the entire slot */

	dev = pci_scan_single_device(bus, devfn);//扫描设备,根据功能号
	if (!dev)
		return 0;
	if (!dev->is_added)
		nr++;

	.
        .
        .
	return nr;
}
继续,
struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
{
	struct pci_dev *dev;

	dev = pci_get_slot(bus, devfn);//看看slot上是不是已经有devfn对应的设备了
	if (dev) {
		pci_dev_put(dev);
		return dev;
	}

	dev = pci_scan_device(bus, devfn); //slot上还没有,那就扫描一下
	if (!dev)
		return NULL;

	pci_device_add(dev, bus);

	return dev;
}

继续看pci_scan_device()

static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
{
	struct pci_dev *dev;
	u32 l;

	if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) //读一读硬件,看看有没有devfn的设备存在
		return NULL;

	dev = pci_alloc_dev(bus); //有硬件设备存在,那就创建一个struct pci_dev的对象来代表它吧
	if (!dev)
		return NULL;

	dev->devfn = devfn;
	dev->vendor = l & 0xffff;
	dev->device = (l >> 16) & 0xffff;

	pci_set_of_node(dev); //看看device tree dts里有信息没

	if (pci_setup_device(dev)) { //初始化pci_dev对象,包括vendor,id,class信息。
		pci_bus_put(dev->bus);
		kfree(dev);
		return NULL;
	}

	return dev;
}
好了,基本的步骤就是如此。当然扫描还会一层一层的走下去,因为如果有pci桥,就会多一层。

还有热插拔的设备,插上后会被创建device。

看完struct pci_dev的创建,就能更完整地理解pci驱动的架构了。


On kernel 4.3, the following list shows the sequence of the PCI bus create and scan.

Dec  9 17:43:25 ubuntu kernel: [    0.538740] alexTrace: acpi_init() acpi_disabled=0
Dec  9 17:43:25 ubuntu kernel: [    0.613669] alexTrace: acpi_pci_root_init register pci_root_handler
Dec  9 17:43:25 ubuntu kernel: [    0.775337] alexTrace: acpi_pci_root_add
Dec  9 17:43:25 ubuntu kernel: [    0.781491] alexTrace,pci_acpi_scan_root
Dec  9 17:43:25 ubuntu kernel: [    0.784897] alexTrace: pci_create_root_bus
Dec  9 17:43:25 ubuntu kernel: [    0.789678] alexdebug: pci_scan_child_bus
Dec  9 17:43:25 ubuntu kernel: [    0.789730] alexdebug: pci_scan_slot devfn 0
Dec  9 17:43:25 ubuntu kernel: [    0.789776] alexdebug: pci_scan_single_device devfn=0
Dec  9 17:43:25 ubuntu kernel: [    0.789883] alexdebug: pci_scan_device devfn=0,debugcount=0
Dec  9 17:43:25 ubuntu kernel: [    0.914795] alexdebug: pci_scan_bridge
Dec  9 17:43:25 ubuntu kernel: [    0.914812] alexdebug: pci_scan_child_bus

The first PCI scan starts from ACPI.

If ACPI is disabled, then it starts from pci_legacy_init().




2017-03-25 15:36:00 chuanzhilong 阅读数 12348
  • python全栈开发devops方向初到

    课程包含前端后端由浅入深,所有的课程全程以项目开发为主线进行讲解,作业题紧跟项目开发,让大家学完后,能够迅速巩固,大大降低了大学学习语法的时间。课程内容耗时一年精心准备,经过精编,单节课课时一般在15-30分钟。 包含项目:一共4个项目(用户系统 cmdb ansible任务管理系统 项目发布系统),并包含源码。

    3808 人正在学习 去看看 李哲

linux中在/dev/下手动创建设备节点

/dev/目录下有许多设备节点文件,比如u盘的文件/dev/sda,mmc卡的文件/dev/mmcblk0,这些文件通常是由udev或mdev程序检测到uevent事件后自动创建的。我们也可以通过mknod命令手动创建。


下面mmc卡为例,介绍如何创建其设备节点文件。

1. mknod命令

命令的格式是:
mknod 设备名 设备类型(字符:c,块:b) 主设备号 从设备号

其中,主设备号用来区分不同种类的设备,而次设备号用来区分同一类型的多个设备。

因此,想要创建设备节点,需要知道设备类型,及其主从设备号。

2. 获取设备类型

当设备插入后,我们可以在/proc/devices中看到设备的类型,如下所示。分别显示字符设备与块设备,左边是主设备号,右边的是设备名。所以,mmc卡属于Block设备,主设备号为179,设备名为mmc。
/ # cat /proc/devices 
Character devices:
  1 mem
  2 pty
  3 ttyp
  4 /dev/vc/0
...
254 ttySDIO

Block devices:
  1 ramdisk
259 blkext
  7 loop
179 mmc
/ # 

3. 获取设备的主从设备号

/proc/devices中只显示了主设备号,但是没有从设备号,我们可以通过从sys系统中获取,如下所示。
(1)/sys/block/中可看到mmc卡设备对应的目录为mmcblk0。
(2)我们可在/sys/block/mmcblk0/uevent节点中,看到mmc卡的主设备(MAJOR)为179,从设备号(MINOR)为0,设备类型(DEVTYPE)为磁盘(disk)。
/sys/block/mmcblk0/mmcblk0p1目录,表示该磁盘有1个分区
(3)在/sys/block/mmcblk0/mmcblk0p1/uevent节点中,看到mmc卡的主设备(MAJOR)为179,从设备号(MINOR)为1,设备类型(DEVTYPE)为分区(partition)。
/ # ls /sys/block/
loop0    loop4    mmcblk0  ram11    ram15    ram5     ram9
loop1    loop5    ram0     ram12    ram2     ram6
loop2    loop6    ram1     ram13    ram3     ram7
loop3    loop7    ram10    ram14    ram4     ram8
/ # ls /sys/block/mmcblk0/
bdi         device      mmcblk0p1   removable   slaves      uevent
capability  ext_range   queue       ro          stat
dev         holders     range       size        subsystem
/ # cat /sys/block/mmcblk0/uevent 
MAJOR=179
MINOR=0
DEVTYPE=disk
PHYSDEVPATH=/class/mmc_host/mmc0/mmc0:0002
PHYSDEVBUS=mmc
PHYSDEVDRIVER=mmcblk
/ # 
/ # cat /sys/block/mmcblk0/mmcblk0p1/uevent 
MAJOR=179
MINOR=1
DEVTYPE=partition
PHYSDEVPATH=/class/mmc_host/mmc0/mmc0:0002
PHYSDEVBUS=mmc
PHYSDEVDRIVER=mmcblk
/ # 

4. 创建节点

使用mknod命令,分别创建磁盘和分区的节点。
mknod /dev/mmcblk0 b 179 0
mknod /dev/mmcblk0p1 b 179 1
创建后,可在/dev/目录下看到刚创建的节点如下。
/ # ls /dev/mmcblk0* -l
brw-r--r--    1 root     root     179,   0 Jan  1 00:34 /dev/mmcblk0
brw-r--r--    1 root     root     179,   1 Jan  1 00:36 /dev/mmcblk0p1

5. 挂载分区

挂载分区后,我们就可以访问mmc卡中的文件了。
/ # mount /dev/mmcblk0p1 /mnt/
/ # ls /mnt/
a                dd               x.docx
/ # 

6. 删除节点

删除节点,就像删除普通文件一样,如下所示。
/ # rm /dev/mmcblk0p1 -f
/ # 
/ # ls /dev/mmcblk0* -l
brw-r--r--    1 root     root     179,   0 Jan  1 00:34 /dev/mmcblk0
/ # 

好啦,至此,手动创建节点的方法已经介绍完了,^-^。

2012-08-30 23:51:08 TheGameIsFives 阅读数 2316
  • python全栈开发devops方向初到

    课程包含前端后端由浅入深,所有的课程全程以项目开发为主线进行讲解,作业题紧跟项目开发,让大家学完后,能够迅速巩固,大大降低了大学学习语法的时间。课程内容耗时一年精心准备,经过精编,单节课课时一般在15-30分钟。 包含项目:一共4个项目(用户系统 cmdb ansible任务管理系统 项目发布系统),并包含源码。

    3808 人正在学习 去看看 李哲

linux kernel从 2.6 到 3.0 3.4  ...    devfs已经被抛弃。  kernel交互的方式有 sysfs procfs 还有就是/dev下的节点, 这些节点是如何被创建出来的呢。
研究了半天,在kernel device_create代码看了遍,也只是发现创建了一堆sysfs节点和一些link。
最后才发现是用户空间创建的。 android系统在
system/core/init/ueventd.c
if (ufds[0].revents == POLLIN)
handle_device_fd(device_fd);
system/core/init/devices.c: handle_device_event->make_device
通过接收uevent来动态添加/dev下节点

对于 linux pc 是采用udev来代替早期的devfs 在一个守护进程中实现/dev下节点的动态添加。
嵌入式linux中,busybox继承了一个简化版的udev,叫mdev。

 

2019-07-17 20:28:42 Mr_XiangShuai 阅读数 44
  • python全栈开发devops方向初到

    课程包含前端后端由浅入深,所有的课程全程以项目开发为主线进行讲解,作业题紧跟项目开发,让大家学完后,能够迅速巩固,大大降低了大学学习语法的时间。课程内容耗时一年精心准备,经过精编,单节课课时一般在15-30分钟。 包含项目:一共4个项目(用户系统 cmdb ansible任务管理系统 项目发布系统),并包含源码。

    3808 人正在学习 去看看 李哲

1、 yum install automake gcc kernel-devel

2、cd /temp

3、tar xvf /usr/lib/vmware/modules/source/vmmon.tar

4、cd vmmon-only/

5、make

6、cp vmmon.ko /lib/modules/2.6.32-504.el6.x86_64/misc/vmmon.ko

(后面这个数字参考自己的版本,make后会出现)

7、modprobe vmmon

可能会出错,提示(modprobe: ERROR: could not insert ‘vmmon‘ : Required key not available)
原因:可能你要装的是windows系统,windows系统出厂时会在BIOS内设置secure boot,该模块将会禁止windows系统与windows非授权系统共存(windows的自我保护,也称垄断)
解决办法:进入BIOS,将secure boot的值改为diable,保存配置并退出

8、重新重第一步做起就可以了

2013-08-03 15:14:32 kaly_liu 阅读数 14
  • python全栈开发devops方向初到

    课程包含前端后端由浅入深,所有的课程全程以项目开发为主线进行讲解,作业题紧跟项目开发,让大家学完后,能够迅速巩固,大大降低了大学学习语法的时间。课程内容耗时一年精心准备,经过精编,单节课课时一般在15-30分钟。 包含项目:一共4个项目(用户系统 cmdb ansible任务管理系统 项目发布系统),并包含源码。

    3808 人正在学习 去看看 李哲

友善之臂的Tiny210 linux3.0.8 for android

实现:在linux内核下添加LED的驱动 LED@LZM@FJICC并且可以在# /dev/下看到。

#ls /dev/  看到驱动LED@LZM@FJICC

1.进入linux/drivers/char/新建一个文件lzm_fjicc.c

编写内容:

//lzm_fjicc.c

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/miscdevice.h>

#include <linux/fs.h>

#include <linux/types.h>

#include <linux/moduleparam.h>

#include <linux/slab.h>

#include <linux/ioctl.h>

#include <linux/cdev.h>

#include <linux/delay.h>

#include <mach/gpio.h>

#include <mach/regs-gpio.h>

#include <plat/gpio-cfg.h>

 

#define DEVICE_NAME "LED@LZM@FJICC"

static int led_gpios[] = {

       S5PV210_GPJ2(0),

       S5PV210_GPJ2(1),

       S5PV210_GPJ2(2),

       S5PV210_GPJ2(3),

};

 

#define LED_NUMARRAY_SIZE(led_gpios)

 

 

static long fjicc_leds_ioctl(struct file *filp, unsigned int cmd,

              unsigned long arg)

{

       switch(cmd) {

              case 0:

              case 1:

                     if (arg > LED_NUM) {

                            return -EINVAL;

                     }

 

                     gpio_set_value(led_gpios[arg], !cmd);

                     //printk(DEVICE_NAME": %d %d\n", arg, cmd);

                     break;

 

              default:

                     return -EINVAL;

       }

 

       return 0;

}

 

static struct file_operations fjicc_led_dev_fops = {

       .owner                  = THIS_MODULE,

       .unlocked_ioctl       = fjicc_leds_ioctl,

};

 

static struct miscdevice fjicc_led_dev = {

       .minor                   = MISC_DYNAMIC_MINOR,

       .name                    = DEVICE_NAME,

       .fops                     = &fjicc_led_dev_fops,

};

 

static int __init fjicc_led_dev_init(void) {

       int ret;

       int i;

 

       for (i = 0; i < LED_NUM; i++) {

              ret = gpio_request(led_gpios[i], "LED");

              if (ret) {

                     printk("%s: request GPIO %d for LED failed, ret = %d\n", DEVICE_NAME,

                                   led_gpios[i], ret);

                     return ret;

              }

 

              s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);

              gpio_set_value(led_gpios[i], 1);

       }

 

       ret = misc_register(&fjicc_led_dev);

 

       printk(DEVICE_NAME"\tinitialized\n");

 

       return ret;

}

 

static void __exit fjicc_led_dev_exit(void) {

       int i;

 

       for (i = 0; i < LED_NUM; i++) {

              gpio_free(led_gpios[i]);

       }

 

       misc_deregister(&fjicc_led_dev);

}

 

module_init(fjicc_led_dev_init);

module_exit(fjicc_led_dev_exit);

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("LZM@FJICC");

 

2.然后修改char目录下的KconfigMakefile文件

Kconfig:

config LEDS_LZM_FJICC

       tristate "LEDS_LZM_FJICC"

       depends on MACH_MINI210

       default y

       help

         This option enables support for LEDs connected to GPIO lines

         on Mini210 boards.

 

Makefile:

obj-$(CONFIG_LEDS_LZM_FJICC)   += lzm_fjicc.o

 

3.进到linux根目录,然后#make menuconfig

就可以在配置菜单中看到LEDS_LZM_FJICC,具体在devices driversàchracter devicesà就可以看到了。

4.配置好了,make zImage就可以了。

5.烧写了系统后,就可以查看驱动了。#ls /dev/

6.提升驱动权限:#chmod 777 /dev/LED@LZM@FJICC

linux来创建分区

阅读数 2397

Linux下创建RAID

阅读数 32

没有更多推荐了,返回首页