您的位置:首页 > 其它

usb更新文件

2016-03-02 11:18 148 查看
一.内核配置,配置使其支持u盘
make menu_config
Device Drivers --->
[*]USB support -->
<*> USB Mass Storage support
u盘底层依赖scsi,所以scsi的配置也要配置好
二.设计更新代码
我是这么设计的:写个应用程序存放在文件系统的/bin目录下,取名update,执行这个程序会遍历 /dev/sd[drive][partition],
执行里面定义好的脚本文件,文件名约定为UpDate,脚本文件就可以调用busybox的通用linux命令,rm,mkdir,cp,touch等命令
将u盘上的新二进制或其他文件替换掉旧的文件系统的文件.
2.1 update代码
<span style="background-color: rgb(255, 255, 255);">#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

unsigned char ch[8]={'a','b','c','d','e','f','g','h'}; //sda,sdb,sdc
int main(int argc,char **argv)
{
int fd;
unsigned char DEV[64];	//u盘等磁盘设备的设备文件路径
unsigned char PATH[64];	//Update文件的路径
unsigned char cmd[64];	//系统调用的命令
int i=0;
int j=0;

for(j=0;j<4;j++){	//最多支持4个分区
for(i=0;i<8;i++){	//最多8个硬盘
sprintf(PATH,"/media/sd%c%d/UpDate",ch[i],j); //"/media/sda1/UpDate","/media/sda2/UpDate"...
sprintf(DEV,"/media/sd%c%d",ch[i],j);  //对应的设备文件路径"/media/sda1","/media/sda2"...
fd=open(PATH,O_RDWR);    //打开文件全路径
if(fd==-1){    //判断文件是否存在
//printf("can not open '%s'\n",PATH);
continue;  //不存在继续扫描下一个分区
}
else{    //文件存在则跳出子循环
printf("open device '%s'\n",PATH);
break;
}
}
if(fd!=-1)    //判断文件是否存在
break;   //存在则跳出第二个for循环,不存在则继续下一个磁盘扫描
}
if(fd==-1){ //判断文件是否存在
printf("can not find any u pan!\n ");  //这表示所有磁盘所有分区都没有UpDate文件
}
else{    //文件存在
close(fd);  //关闭文件描述符
sprintf(cmd,"sh %s %s",PATH,DEV);  //设计执行脚本命令,例如"sh /media/sda1/UpDate /media/sda1"
system(cmd);   //执行该脚本
}
return 0;
}</span>

这里cmd将设备文件路径作为第一个参数传递给脚本
那么执行的脚本里面就可以通过$1获取DEV(/media/sda1)
可以写个简单的脚本测试下
<span style="background-color: rgb(255, 255, 255);">#! /bin/sh
echo -e "update file!"
echo $1
ls -l $1
touch /opt/1234
echo -e "update file done!"</span>


ok交叉编译应用程序update然后放在/bin下面吧
到这里可以在启动代码的执行脚本中执行/bin/update文件来执行u盘中UpDate更新程序了
但是事先必须先插上u盘才能在启动过程中执行启动脚本调用到update --重启自动
或者只能插上u盘手工运行update来更新程序. --手动
三.下面来做不用重启的自动,也就是插上u盘自动运行update
先测试下u盘插入到识别的原理吧
3.1插入u盘打印
<span style="background-color: rgb(255, 255, 255);">usb 1-1: new high speed USB device using musb-hdrc and address 5
usb 1-1: New USB device found, idVendor=0951, idProduct=1643
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: DataTraveler G3
usb 1-1: Manufacturer: Kingston
usb 1-1: SerialNumber: 001CC0EC34F1FB90F71729FF
scsi5 : usb-storage 1-1:1.0
scsi 5:0:0:0: Direct-Access     Kingston DataTraveler G3  1.00 PQ: 0 ANSI: 0 CCS
sd 5:0:0:0: Attached scsi generic sg0 type 0
sd 5:0:0:0: [sdb] 15644912 512-byte logical blocks: (8.01 GB/7.45 GiB)
sd 5:0:0:0: [sdb] Write Protect is off
sd 5:0:0:0: [sdb] Assuming drive cache: write through
sd 5:0:0:0: [sdb] Assuming drive cache: write through
sdb: sdb1
sd 5:0:0:0: [sdb] Assuming drive cache: write through
sd 5:0:0:0: [sdb] Attached SCSI removable disk
FAT: invalid media value (0xb9)
VFS: Can't find a valid FAT filesystem on dev sdb.
EXT3-fs (sdb): error: can't find ext3 filesystem on dev sdb.
EXT2-fs (sdb): error: can't find an ext2 filesystem on dev sdb.
FAT: invalid media value (0xb9)
VFS: Can't find a valid FAT filesystem on dev sdb.
ISOFS: Unable to identify CD-ROM format.</span>


hub_thread守护线程[khubd]检测到hub状态变化,根hub枚举新的usb设备,获取新的usb设备信息,创建usb_device(usb设备),调用usb_bus_type的match方法,找到对应的usb驱动(usb_driver),这里就是usb_storage_driver.匹配之后调用usb_storage_driver的probe方法storage_probe,接着usb_stor_probe2函数,接着创建一个usb_stor_scan_thread线程来扫描u盘
<span style="background-color: rgb(255, 255, 255);">usb_stor_scan_thread
scsi_scan_host
do_scsi_scan_host
scsi_scan_host_selected
scsi_scan_channel
__scsi_scan_target
scsi_probe_and_add_lun
scsi_add_lun
scsi_sysfs_add_sdev</span>


接着调用sisc总线scsi_bus_type的match方法,匹配接着sd_probe,接着sd_probe_async同步
接着调用/bin/mount创建设备节点
update的扫描是扫描设备节点,mount命令会调用系统调用sys_mount
所以我在sys_mount的方法中调用update
sys_mount定义在fs/namespace.c中
<span style="background-color: rgb(255, 255, 255);">SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
char __user *, type, unsigned long, flags, void __user *, data)
{
int ret;
char *kernel_type;
char *kernel_dir;
char *kernel_dev;
unsigned long data_page;

ret = copy_mount_string(type, &kernel_type);
if (ret < 0)
goto out_type;

kernel_dir = getname(dir_name);
if (IS_ERR(kernel_dir)) {
ret = PTR_ERR(kernel_dir);
goto out_dir;
}

ret = copy_mount_string(dev_name, &kernel_dev);
if (ret < 0)
goto out_dev;

ret = copy_mount_options(data, &data_page);
if (ret < 0)
goto out_data;

ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,
(void *) data_page);

call_usermodehelper ("/bin/update", NULL, NULL, 1); //MHB update ---就加了这句ok
free_page(data_page);
out_data:
kfree(kernel_dev);
out_dev:
putname(kernel_dir);
out_dir:
kfree(kernel_type);
out_type:
return ret;
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: