现在的位置: 首页 > 综合 > 正文

linux硬链接与软链接 linux asm 文件

2013年10月08日 ⁄ 综合 ⁄ 共 4751字 ⁄ 字号 评论关闭

今天阅读嵌入式linux LED驱动程序的时候

驱动实现部分是搞清楚了

但是几个头文件的路径真的把我搞糊涂了LINUX 2.6.13文件组织如下


头文件如下


#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>


可我根本就找不到ARM对应的asm这个文件夹,或者说找到了也对应的不是对应S3C24XX的

后来无意间看内核移植的一篇文章讲了链接的实例

所以asm文件应该也是一个连接,那么一切就说的通了


asm文件连接到\kernel-2.6.13\include\asm-arm文件夹下

#include <asm/irq.h>                                        ==\kernel-2.6.13\include\asm-arm\irq.h
#include <asm/arch/regs-gpio.h>                  ==kernel-2.6.13\include\asm-arm\arch-s3c2410\regs-gpio.h
#include <asm/hardware.h>                           ==\kernel-2.6.13\include\asm-arm\hardware.h


所以我猜测如果你看到

#include <mach/regs-gpio.h>

可能意思是

mach  ==kernel-2.6.13\arch\arm\mach-s3c2410

#include <linux/interrupt.h>           操作系统中断
#include <asm/uaccess.h>               与处理器相关的入口
//#include <asm/arch/regs-gpio.h>          与处理器相关的IO口操作
#include <mach/regs-gpio.h>                   同上
//#include <asm/hardware.h>                 与处理器相关的硬件
#include <mach/hardware.h>                   同上

http://www.cnblogs.com/sonic4x/archive/2011/08/05/2128543.html

linux硬链接与软链接

1.Linux链接概念
Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。默认情况下,ln命令产生硬链接。

【硬连接】
硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止误删的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

硬连接的2个限制:

l  不允许给目录创建硬链接

l  只有在同一文件系统中的文件之间才能创建链接。 即不同硬盘分区上的两个文件之间不能够建立硬链接。这是因为硬链接是通过结点指向原始文件的,而文件的i-结点在不同的文件系统中可能会不同。

 

【软连接】
另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。

      这就允许符号链接(经常简写为symlinks)指向位于其他分区、甚至是其他网络硬盘上的某个文件

 

2.通过实验加深理解
[oracle@Linux]$ touch f1          #创建一个测试文件f1
[oracle@Linux]$ ln f1 f2          #创建f1的一个硬连接文件f2
[oracle@Linux]$ ln -s f1 f3       #创建f1的一个符号连接文件f3
[oracle@Linux]$ ls -li            # -i参数显示文件的inode节点信息
total 0
9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f1
9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f2
9797649 lrwxrwxrwx  1 oracle oinstall 2 Apr 21 08:11 f3 -> f1

从上面的结果中可以看出,硬连接文件f2与原文件f1inode节点相同,均为9797648,然而符号连接文件的inode节点不同。

[oracle@Linux]$ echo "I am f1 file" >>f1
[oracle@Linux]$ cat f1
I am f1 file
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
I am f1 file
[oracle@Linux]$ rm -f f1
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
cat: f3: No such file or directory

通过上面的测试可以看出:当删除原始文件f1后,硬连接f2不受影响,但是符号连接f3文件无效

3.总结
依此您可以做一些相关的测试,可以得到以下全部结论:
1).删除符号连接f3,f1,f2无影响;
2).删除硬连接f2,对f1,f3也无影响;
3).删除原文件f1,对硬连接f2没有影响,导致符号连接f3失效;
4).同时删除原文件f1,硬连接f2,整个文件会真正的被删除。

下面是一个简单的LED驱动程序实例

http://blog.mcuol.com/User/gaochengnan/Article/13406_1.htm

另外可参考

http://hi.baidu.com/tekuba/item/d72e32eb8f19713d86d9de94

http://longer.spaces.eepw.com.cn/articles/article/item/60415

led驱动实验
源码gaoled.c:

 #include "linux/config.h"
#include "linux/module.h"
#include "linux/kernel.h"
#include "linux/fs.h"
#include "linux/init.h"
#include "linux/devfs_fs_kernel.h"
#include "linux/miscdevice.h"
#include "linux/delay.h"
#include "asm/irq.h"
#include "asm/arch/regs-gpio.h"
#include "asm/hardware.h"
 
#define DEVICE_NAME  "gcnled"           //定义设备名
#define LED_MAJOR 250                  //手动定义主设备号
 
MODULE_AUTHOR("gcn");
MODULE_DESCRIPTION("S3C2440 LED Driver");
MODULE_LICENSE("GPL");
 
//定义要操作的设备,把每一个led作为结构体的一个成员
static unsigned long led_table [] =
{          
    S3C2410_GPF4,
    S3C2410_GPF5,
    S3C2410_GPF6,
    S3C2410_GPF7,
};
//对设备进行设置,此即5个管脚为输出口
static unsigned int led_cfg_table [] =
{
    S3C2410_GPF4_OUTP,
    S3C2410_GPF5_OUTP,
    S3C2410_GPF6_OUTP,
    S3C2410_GPF7_OUTP,
};
/*编写s3c2440_led_ioctl函数:设备驱动程序中对设备的I/O通道进行管理的函数,用来实现对led的操作*/是整个驱动程序的核心*/
static int s3c2440_leds_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
 if (arg > 3)
{
           return -EINVAL;
          }
led(cmd)
{
           case 0:
           case 1:
          s3c2410_gpio_setpin(led_table[arg], !cmd);
           return 0;
           default:
           return -EINVAL;
         }
}
//定义s3c2440_led_fops:结构体提供基本函数入口点
static struct file_operations s3c2440_leds_fops =
    {
        .owner =   THIS_MODULE,
        .ioctl =   s3c2440_leds_ioctl,
};
//模块加载函数
static int __init s3c2440_leds_init(void)
{
    int ret;
    int i;
//注册设备号/* register_chrdev是注册字符设备的函数*/
    ret=register_chrdev(LED_MAJOR,DEVICE_NAME,&s3c2440_leds_fops);
    if (ret < 0)
{
             printk(DEVICE_NAME " can''''''''''''''''''''''''''''''''t register major number\n");
             return ret;
           }
/* 2.6内核驱动注册完后,要用以下代码创建设备文件*/
devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);
for (i = 0; i < 4; i++)
{
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
/*相当于open函数将相应端口设置为输出口*/
s3c2410_gpio_setpin(led_table[i], 1);/*端口置1*/
}
printk(DEVICE_NAME " initialized\n");/*打印出驱动加载成功的信息*/
    return 0;
}
//模块卸载函数
static void __exit s3c2440_leds_exit(void)
{
    devfs_remove(DEVICE_NAME);/* 2.6内核驱动要用以下代码移除设备文件*/
    unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}
//指定驱动程序的初始化函数和卸载函数
module_init(s3c2440_leds_init);
module_exit(s3c2440_leds_exit);
 
 
把gaoled.c考入内核目录下的/devices/char目录下
修改该目录下的makefile:Obj-m += gaoled.o
在内核根目录下运行make modules
会发现生成了gaoled.ko文件
接下来把gaoled.ko转移到开发板上(我是直接用优盘考出来在开发板上挂载的)
在gaoled.c目录下运行 insmod gaoled.ko
打印出gcnled initialized
成功!
查看是否成功可以在开发板上进入/ proc下执行cat devices 可以看到 250 gcnled
注意:编译生成.ko文件是在pc机完成的。
          然后在开发板上加载模块insmod xxx.ko
  
出现问题:devices busy 设备忙碌什么的因为主设备号重复了!我刚开始用的231 改成250之后就好了
 以上均亲身实践测试程序通过 

抱歉!评论已关闭.