6.5.1.Menuconfig工具操作说明
按键 | 描述 |
---|---|
上下方向键 | 切换菜单 |
左右方向键 | 切换Menuconfig工具底部、、三个按钮 |
Enter键 | 确认键,起到确认作用 |
高亮字母 | 如上图菜单和底部按钮的第一个字母是高亮。在键盘上按下对应高亮字母键,可直接选择对应的菜单或底部按钮 |
空格键 | 选择目标菜单后按空格键切换启用、禁用和可加载模块(启用是指菜单对应的功能会被编译;禁用是指菜单对应功能不会被编译;可加载模块是指将菜单对应的功能编译为可加载模块,可加载模块特点在于功能不被编译进镜像,在编译时会被单独处理,生成独立的文件(通常以.ko为扩展名)。在需要这个功能时,可通过insmod、rmmod或modprobe等命令将这个功能动态地加载进内核;而不需要时,可以将它从内存中卸载掉,从而避免功能驻留在内存中,造成内存浪费)。启用、禁用和可加载模块对应的快捷键分别是Y、N和M |
双击Esc键 | 放回上一级或退出Menuconfig工具。功能同底部键 |
?键 | 查看相应菜单的帮助信息。功能同底部键 |
/键 | 按下/键后进入搜索界面,然后输入文字进行搜索 |
其它说明: [ * ]和< * >:表示启用 [ ]和< >:表示禁用 < M >:表示可加载模块 |
6.5.2.定制Linux内核步骤
第1步:执行sudo apt-get install libncurses5-dev命令安装ncurses库(ncurses库为Menuconfig工具提供界面支持)
第2步:在顶层目录下输入make menuconfig命令打开Menuconfig工具。注意:若报Your display is too small to run Menuconfig!错误,则说明终端窗口太小,请调大终端窗口
第3步:根据自己的需求按照“Menuconfig工具操作说明”章节操作菜单
第4步:退出Menuconfig工具,在退出时请选择“yes”按钮保存配置,如下图:
保存成功后,会将配置结果更新于顶层目录的.config文件中,以便编译时使用。
第5步:编译并烧写
6.6.添加Linux内核功能
为满足特定的需求,用户可以根据需求编写代码添加到Linux内核中。
6.6.1.过程
第1步:在相应目录中创建一个C源文件
第2步:在C源文件中编写功能代码
第3步:在C源文件所在目录中的Kconfig文件中添加配置选项代码
- 备注1:若目录中没有Kconfig文件,则需要创建Kconfig文件
- 备注2:Kconfig文件的语法规则参考“Kconfig系统”章节
- 备注3:此步骤可选,若想要此功能像“定制Linux内核”章节介绍的一样可配置,则需要此步骤,否则可忽略此步骤
第4步:在C源文件所在目录中的Makefiel文件中添加如下代码:
obj-y += <创建的.c文件名>.o
或
obj-$(CONFIG_<第②步添加的配置选项标识>) += <创建的.c文件名>.o
- 备注1:若在Makefile文件中添加的是上述第一句代码,则创建的C源文件会被无条件的编译
- 备注2:若在Makefile文件中添加的是上述第二句代码,则创建的C源文件是否被编译由第3步添加的配置选项控制
第5步:编译并烧写
第6步:测试是否添加成功
6.6.2.示例:添加Beep驱动
第1步:在drivers/char目录中创建一个beep_driver.c文件
第2步:在beep_driver.c文件中编写功能代码,代码如下:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <mach/gpio.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <mach/soc.h>
#include <mach/platform.h>
#define LED_0 0
struct class *beep_class;
struct device *beep_device;
static int major = 0;
static int beep_open(struct inode *pnode, struct file *filp)
{
return 0;
}
static ssize_t beep_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
int value = 0;
if(count!=1)
return -1;
if(nxp_soc_gpio_get_io_dir(PAD_GPIO_C+14))
value = nxp_soc_gpio_get_out_value(PAD_GPIO_C+14);
else
value = nxp_soc_gpio_get_in_value(PAD_GPIO_C+14);
return sizeof(int)-copy_to_user(buff,&value,sizeof(int));
}
static ssize_t beep_write(struct file *pnode,const char __user *buff,size_t count,loff_t *offp)
{
int value = 0;
int len = 0;
if(count>sizeof(int))
return -1;
len = copy_from_user(&value,buff,sizeof(int));
nxp_soc_gpio_set_out_value(PAD_GPIO_C+14,(!(!value)));
return (1-len);
}
static long beep_ioctl(struct file *filp, unsigned int cmd, unsigned long data)
{
if(cmd)
nxp_soc_gpio_set_out_value(PAD_GPIO_C+14,1);
else
nxp_soc_gpio_set_out_value(PAD_GPIO_C+14,0);
return 0;
}
static int beep_release(struct inode *pnode, struct file *filp)
{
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.read = beep_read,
.write = beep_write,
.open = beep_open,
.unlocked_ioctl = beep_ioctl,
.release = beep_release,
};
static int __init beep_init(void)
{
major = register_chrdev(0,"vmotor_drv", &fops);
if(major<0)
{
printk(KERN_CRIT "error register_chrdev\n");
goto err_reg;
}
beep_class=class_create(THIS_MODULE, "vmotor_cls");
if(IS_ERR(beep_class))
{
printk(KERN_CRIT "error class_create\n");
goto err_cls;
}
beep_device=device_create(beep_class, NULL,MKDEV(major,0),NULL,"vmotor");
if(IS_ERR(beep_device))
{
printk(KERN_CRIT "error device_create\n");
goto err_dev;
}
nxp_soc_gpio_set_io_dir(PAD_GPIO_C+14, 1);
return 0;
err_dev:
class_destroy(beep_class);
err_cls:
unregister_chrdev(major,"vmotor_drv");
err_reg:
return -1;
};
static void __exit beep_exit(void)
{
unregister_chrdev(major,"vmotor_drv");
device_destroy(beep_class,MKDEV(major,0));
class_destroy(beep_class);
return;
};
module_init(beep_init);
module_exit(beep_exit);
MODULE_LICENSE("GPL");
第3步:在drivers/char目录中的Kconfig文件中添加如下代码
config BEEP_DRIVER
bool "Provide the on and off interface for the Beep"
default y
第4步:在drivers/char目录中的Makefiel文件中添加如下代码
obj-$(CONFIG_BEEP_DRIVER) += beep_driver.o
第5步:编译并烧写
第6步:测试
- 第①步:在Ubuntu中创建beep.c文件,代码如下。此代码用于调用beep_driver.c提供的接口,以便测试“beep驱动”是否添加成功
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <string.h>
#include <asm/ioctl.h>
#include <linux/input.h>
#define BCT3288A_CLOSE _IO('B',1)
#define BCT3288A_CLEAR _IO('B',2)
int main(int argc,char *argv[])
{
int fd;
int value;
unsigned char buf[2];
fd = open("/dev/beep",O_RDWR);
if(fd<0)
{
perror("dev tain open:");
return 1;
}
if(argc > 0)
{
value = atoi(argv[1]);
}
ioctl(fd,value);
close(fd);
return 0;
}
- 第②步:交叉编译beep.c文件,执行交叉编