一.内核配置,配置使其支持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代码
[cpp] view
plain copy
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
unsigned char ch[8]={'a','b','c','d','e','f','g','h'};
-
int main(int argc,char **argv)
-
{
-
int fd;
-
unsigned char DEV[64];
-
unsigned char PATH[64];
-
unsigned char cmd[64];
-
int i=0;
-
int j=0;
-
-
for(j=0;j<4;j++){
-
for(i=0;i<8;i++){
-
sprintf(PATH,"/media/sd%c%d/UpDate",ch[i],j);
-
sprintf(DEV,"/media/sd%c%d",ch[i],j);
-
fd=open(PATH,O_RDWR);
-
if(fd==-1){
-
-
continue;
-
}
-
else{
-
printf("open device '%s'
",PATH);
-
break;
-
}
-
}
-
if(fd!=-1)
-
break;
-
}
-
if(fd==-1){
-
printf("can not find any u pan!
");
-
}
-
else{
-
close(fd);
-
sprintf(cmd,"sh %s %s",PATH,DEV);
-
system(cmd);
-
}
-
return 0;
-
}
这里cmd将设备文件路径作为第一个参数传递给脚本
那么执行的脚本里面就可以通过$1获取DEV(/media/sda1)
可以写个简单的脚本
测试下
[cpp] view
plain copy
-
#! /bin/sh
-
echo -e "update file!"
-
echo $1
-
ls -l $1
-
touch /opt/1234
-
echo -e "update file done!"
ok交叉编译应用程序update然后放在/bin下面吧
到这里可以在启动代码的执行脚本中执行/bin/update文件来执行u盘中UpDate更新程序了
但是事先必须先插上u盘才能在启动过程中执行启动脚本调用到update --重启自动
或者只能插上u盘手工运行update来更新程序. --手动
三.下面来做不用重启的自动,也就是插上u盘自动运行update
先测试下u盘插入到识别的原理吧
3.1插入u盘打印
[cpp] view
plain copy
-
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.
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盘
[cpp] view
plain copy
-
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
接着调用sisc总线scsi_bus_type的match方法,匹配接着sd_probe,接着sd_probe_async同步
接着调用/bin/mount创建设备节点
update的扫描是扫描设备节点,mount命令会调用系统调用sys_mount
所以我在sys_mount的方法中调用update
sys_mount定义在fs/namespace.c中
[cpp] view
plain copy
-
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
-
char __user *, type, unsigned long, flags, void __user *, data)
-
{
-