驱动:内核编译

内核源码目录,第一个目录——顶层目录,如下

内核编译:makefile

一、条件编译

自己编译内核步骤

1.cp config_mini2440_td355.config  第一次编译内核(仅一次)

2.make menuconfig  每次有文件增删时

3.make uImage  每次编译

4. 拷贝新的uImage至tftpboot目录下,替换旧的uImage(把旧的删了) 

5. 重新下载内核(tftp 0x30008000 uImage),下载成功后再启动(bootm 30008000),无报错,即成功

错误

make uImage时提示信息

启动时,提示错误信息 

错误处理 

1. 修改入口地址entry point 

 2. 修改之后重新编译 

3. 重新make uImage,拷贝uImage,再重新下载内核(tftp 0x30008000 uImage),启动内核

无报错直接启动后即正确启动。 

错误原因

Image ----  可以直接使用的内核映像
zImage ----  一段解压程序+Image的压缩包
uImage ----  64字节的头信息(压缩类型,大小) + zImage

原因头信息不能运行,得偏移过去64字节才能开始运行64字节 = 0x40
        所以入口地址(entry load) 比 加载地址(load address) 多0x40。
        即正确:laod address = 0x30008000,entry point = 0x30008040。

二、编写自己的Kconfig

创建一个config

 

向内核写新目录步骤 

1. 自己写一个目录

在目录 ~/linux-2.6.32.2/drivers/char 下创建一个新文件 kcf,然后 vi Kconfig,即可编写

2. 得在Kconfig里面“声明”一下,menuconfig才会显示

去到上一层目录 ~/linux-2.6.32.2/drivers/char,在原本的 Kconfig “声明”一下,才可生效

3. 在menuconfig界面查看config结果

打开界面查看结果(make meunconfig)

4. 配置选项后,到 ~/linux-2.6.32.2 .config查看配置结果

在 ~/linux-2.6.32.2 目录下 vi .config,查看配置结果

三、向内核新增文件

步骤:=gcc

menuconfig选中新选项,成功提示 

在menuconfig里不选中选项,重新下载uImage,拷贝至tftpboot,内核下载,开机后显示:

四、驱动

驱动(程序):驱使设备行动的程序

驱动程序要素:

  1. 确定一个设备号
  2. 实现必要的系统调用方法(open、read...)
  3. 绑定设备号和对应的操作方法
  4. 向内核注册该驱动节点

驱动模板 

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/cdev.h>

#define MAJOR_NUM  255
#define MINOR_NUM  0
#define DEV_NAME "demo"

static int open(struct inode * node, struct file * file)
{
	printk("demo open ...\n");
	return 0;
}

static ssize_t read(struct file * file, char __user * buf, size_t len, loff_t * loff)
{
	printk("demo read ...\n");
	return 0;
}

static ssize_t write(struct file * file, const char __user * buf, size_t len, loff_t * loff)
{
	printk("demo write ...\n");
	return 0;
}

static int close(struct inode * node, struct file * file)
{
	printk("demo close ...\n");
	return 0;
}

static dev_t dev_num;
static struct cdev dev;
static struct file_operations fops = 
{
	.owner = THIS_MODULE,
	.open = open,
	.read = read,
	.write = write,
	.release = close
};

static int __init demo_init(void)
{
	int ret = 0;
	dev_num = MKDEV(MAJOR_NUM, MINOR_NUM); ;//(MAJOR_NUM << 20) | MINOR_NUM;

	ret = cdev_add(&dev, dev_num, 1);
	if(ret < 0)
		goto err1;

	cdev_init(&dev, &fops);

	ret = register_chrdev_region(dev_num, 1, DEV_NAME);
	if(ret < 0)
		goto err2;

	printk("demo_init   ###############################\n");
	return 0;

err1:
	cdev_del(&dev);
	printk("demo cdev_add failed ret = %d\n", ret);
	return ret;

err2:
	unregister_chrdev_region(dev_num, 1);
	cdev_del(&dev);
	printk("demo register_chrdev_region failed ret = %d\n", ret);
	return ret;
}

static void __exit demo_exit(void)
{
	unregister_chrdev_region(dev_num, 1);
	cdev_del(&dev);
	printk("demo_exit   ###############################\n");
}

module_init(demo_init);
module_exit(demo_exit);

设备号: 32位的数字        

        高12位  主设备号   设备类型  
        低12位  次设备号   同类设备的编号  


运行之前,手动创建设备节点:

mknod /dev/demo c 255 0
// /dev/demo-设备节点名 c-设备类型 255-主设备号 0-次设备号


第一个字符--文件属性 

ls -l 命令列出文件或目录的详细信息时,第一个字符代表文件或目录的类型 

  • -:普通文件
  • d:目录
  • c:字符设备文件。字符设备文件允许访问硬件设备,通常一次处理一个字符,如终端。
          数据的访问是顺序的 (字节流形式)
  • b:块设备文件。也是访问硬件设备,以块为单位进行数据传输,如硬盘、软盘。
          数据访问可以是随机的,一般是存储设备
  • l:符号链接,软连接。类似于快捷方式,指向另一个文件或目录。
  • s:套接字文件
          只有名字,会集成复杂的协议
  • p:管道文件

五、ctag用法

ctrl + ] 进去
ctrl + o/t 出来 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值