tftp方式启动s5pv210并通过nfs挂载根文件系统

说明:文章根据朱老师课堂讲解进行整理

一、通过tftp方式启动内核

在进入到驱动章节时,我们采用tftp的方式下载zimage,zimage是内核的镜像文件,有了它便能将内核启动起来。前提是开发板中已经有了uboot.bin的bootloader启动文件,且在uboot的命令行下开发板能够和虚拟机Ping通。

在启动开发板后,在倒数结束之前按下回车键进入uboot,对uboot的环境变量进行更改,此处修改的是bootcmd命令,

以前通过fastboot烧录进行启动的命令是:

set bootcmd 'movi read kernel 0x30008000;bootm 0x30008000',

修改为tftp启动的命令是
set bootcmd 'tftp 0x30008000 zImage;bootm 0x30008000',修改之后要记得save。这句话的意思是通过tftp获取zimage文件,并将zimage放置在0x30008000地址处,然后内核从0x30008000处开始启动。注意在做这步之前要先在虚拟机中下载并配置好tftp,然后编译内核得到zimage文件,并将zimage放入tftp服务器目录下(此处是自己的虚拟机做服务器),看到如下页面就说明正在通过tftp的方式启动内核

二、通过nfs挂载根文件系统

挂载之前要先配置好nfs,并通过busybox制作自己的一个根文件系统,这两步完成之后通过uboot模式下的命令行修改环境变量中的bootargs,

修改前的bootargs是

setenv bootargs 'root=/dev/nfs nfsroot=192.168.1.141:/root/rootfs ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC2,115200',

修改后的命令是

set    bootargs  root=/dev/nfs nfsroot=192.168.1.141:/root/porting_210/rootfs/rootfs ip=192.168.1.10:192.168.1.141:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC2,115200

需要说明的是nfsroot=192.168.1.141:/root/porting_210/rootfs/rootfs这句话中192.168.1.141是我自己虚拟机的ip地址,此处作为nfs的服务器地址,/root/porting_210/rootfs/rootfs这个是所需要挂载的根文件的文件夹目录,开发者根据自己的目录进行修改

三、在开发板下安装驱动

为了方便,直接对驱动的源码目录下的makefile进行修改,添加cp命令

cp:
    cp *.ko /root/porting_210/rootfs/rootfs/driver_test

在根文件目录下mkdir一个driver_test目录,这样每次在虚拟机下编译完之后,再执行make cp命令便可将生成的.ko的驱动文件复制到根文件目录下,由于根文件系统又通过nfs进行了挂载,所以可以在开发板下对驱动执行操作。

查看设备号的使用情况:cat /proc/devices

先lsmod查看一下驱动,再insmod module_test.ko安装驱动(此处生成的驱动名为module_test.ko),然后再lsmod看一下开发板中的驱动信息,modinfo module_test.ko查看该驱动的详细信息包括内核版本等,卸载的指令是rmmod module_test.ko,最后可使用dmesg命令查看内核日志

创建设备文件的命令是        mknod         /dev/test         c         250         0 

表示在根目录下的dev里创建了test的字符型设备,该设备的主设备号是250,次设备号是0 

四、驱动led的例程

创建一个module_test.c的驱动源文件

#include <linux/module.h>		// module_init  module_exit
#include <linux/init.h>			// __init   __exit
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank.h>


#define GPJ0DAT 			S5PV210_GPJ0DAT
#define GPJ0CON				S5PV210_GPJ0CON

#define rGPJ0CON			*((volatile unsigned int *)GPJ0CON)
#define rGPJ0DAT			*((volatile unsigned int *)GPJ0DAT)

char kbuf[100];

static int test_open(struct inode *inode, struct file *file){	
	rGPJ0CON = 0x11111111;
	rGPJ0DAT = ((0<<3) | (0<<4) | (0<<5));
	printk(KERN_INFO "open led\n");
	return 0;
}

static int test_close(struct inode *inode, struct file *file){	
	rGPJ0CON = 0x11111111;
	rGPJ0DAT = ((1<<3) | (1<<4) | (1<<5));
	printk(KERN_INFO "close led\n");
	return 0;
}

//驱动模块的读函数
int test_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	int ret = -1;
	ret = copy_to_user(buf,kbuf,size);
	if(ret == 0){
		printk(KERN_INFO "chrdev read success\n");
		return 0;
	}
	printk(KERN_INFO "chrdev read failed\n");
	return -1;
}

//驱动模块的写函数
static int test_write(struct file *file,const char __user *user_buf,size_t count, loff_t *ppos)
{
	int ret = -1;
	ret = copy_from_user(kbuf,user_buf,count);
	if(ret == 0){
		printk(KERN_INFO "chrdev write success\n");
		return 0;
	}
	printk(KERN_INFO "chrdev read failed\n");
	return -1;	
}

static const struct file_operations test_fops = {
	.owner		=	THIS_MODULE,
	.write		=	test_write,
	.read  		=   test_read,
	.open		=	test_open,
	.release	=	test_close,
};

int ret = -1;
// 模块安装函数
static int __init chrdev_init(void)
{	
	
	//注册函数
	ret = register_chrdev(0, "module_test", &test_fops);
	if (ret < 0) {
		printk(KERN_ERR "module_test:"
		       "Registering the character device failed with %d\n",
			  ret);
		return 0;
	}
	printk(KERN_INFO "chrdev_init register success,major is %d\n",ret);
	//printk("<7>" "chrdev_init helloworld init\n");
	//printk("<7> chrdev_init helloworld init\n");
	return 0;
}

// 模块下载函数
static void __exit chrdev_exit(void)
{
	//注销函数
	unregister_chrdev(ret, "module_test");
	
	printk(KERN_INFO "chrdev_exit success\n");
}


module_init(chrdev_init);
module_exit(chrdev_exit);

// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL");				// 描述模块的许可证
MODULE_AUTHOR("wuqi_wf");				// 描述模块的作者
MODULE_DESCRIPTION("wuqi_module test");	// 描述模块的介绍信息
MODULE_ALIAS("alias wuqi");			// 描述模块的别名信息

创建一个应用文件对驱动进行调用

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define FILE "/dev/test"

char ubuf[100];

int main(){
	int fd = -1;
	//打开文件
	fd = open(FILE,O_RDWR);
	sleep(4);
	
	if(fd < 0){
		printf("open %s file fail\n",FILE);
		return -1;
	}
	printf("file alread success open\n");
	//后续添加读写接口
	write(fd,"hello world",sizeof(ubuf));
	
	read(fd,ubuf,sizeof(ubuf));
	printf("读取到的驱动数据是%s\n",ubuf);
	//关闭文件
	close(fd);
	printf("file success close");
	
	return 0;
}

在开发板上执行insmod并mknod后,./app灯会亮四秒,并关闭

若有错误,请评论区指出

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值