【Linux】SD卡调试

1)hotplugEventsocket = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
socket 返回Protocol not supported,跟踪libc库中的文件socketcalls.c,socket的系统调用:
int socket(int family, int type, int protocol)
{
     unsigned long args[3];


     args[0] = family;
     args[1] = type;
     args[2] = (unsigned long) protocol;
     return __socketcall(SYS_SOCKET, args);
}
将参数赋值后直接调用了__socketcall,这个是Linux kernel的系统调用函数。


在kernel配置中打开CONFIG_HOTPLUG配置后,问题解决。


2)移出/加入SD卡UDEV信息
移出:
main 113 msg = remove@/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007/block/mmcblk0/mmcblk0p1
event { 'remove', '/devices/platform/mtk-sd.0/mmc_host/mmc0/mmcmsdc0 -> set mclk to 0!!! <- msdc_set_mclk() : L<609> PID<kworker/u:1><0x16>
0:msdc0 -> ops_get_cd return<0> <- msdc_ops_get_cd() : L<2273> PID<kworker/u:1><0x16>
0007/block/mmcblk0/mmcblk0p1', 'block', '', 179, 1 }




main 113 msg = remove@/devices/virtual/bdi/179:0
event { 'remove', '/devices/virtual/bdi/179:0', 'bdi', '', -1, -1 }




main 113 msg = remove@/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007/block/mmcblk0
event { 'remove', '/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007/block/mmcblk0', 'block', '', 179, 0 }




main 113 msg = remove@/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007
event { 'remove', '/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007', 'mmc', '', -1, -1 }


加入:
main 113 msg = ad mmcblk1: p1
d@/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007
SQUASHFS error: Can't find a SQUASHFS superblock on mmcblk1c0:0007', 'mmc', '', -1, -1 }




FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!


main 113 msg = aFAT: bogus number of reserved sectors
ddVFS: Can't find a valid FAT filesystem on dev mmcblk1.
@/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007/block/mmcblk1
event { 'add', '/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007/block/mmcblk1', 'block', '', 179, 8 }
mount: Mounting /tmp/dev/mmcblk1 on /tmp/usbdisk/volume1 failed: Invalid argument




main 113 msg = add@/devices/platform/mtk-sd.0/mmc_host/mmc0/mmc0:0007/block/mmcblk1/mmcblk1p1
event { 'add', '/devices/platform/mtSQUASHFS error: Can't find a SQUASHFS superblock on mmcblk1p1
k-sd.0FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!
/mmc_host/mmc0/mmc0:0007/block/mmcblk1/mmcblk1p1', 'block', '', 179, 9 }




main 113 msg = add@/devices/virtual/bdi/179:8
event { 'add', '/devices/virtual/bdi/179:8', 'bdi', '', -1, -1 }
1 volume(Erase from 0X7E0000 to 0X7ED6C4:s) found.


3)mount 后发现sd卡只读,不能修改文件,通过mount命令查看挂载的信息如下:
# mount
/dev/root on / type squashfs (ro,relatime)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
none on /tmp type ramfs (rw,relatime)
none on /var type ramfs (rw,relatime)
none on /proc/bus/usb type usbfs (rw,relatime)
/tmp/dev/mmcblk0p1 on /tmp/mmcdisk/volume0 type vfat (ro,relatime,fmask=0022,dmask=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
原因是掉电时SD卡保护,会将原来挂载的sd卡变成只读,只需要重新remount一下就可以了。
命令如下:
 mount -t vfat -o remount /tmp/dev/mmcblk0p1 /tmp/mmcdisk/volume0
所以在mount sd卡的时候需要先mount一次,然后读出mount信息,判断是否只读类型,如果是,需要再remount一次。


4)samba的配置文件
# cat smb.conf
[global]
workgroup = WORKGROUP
netbios name = SOHO router
server string =
log file = /tmp/samba/var/%%m.log
max log size = 5
log level = 0
security = share
max connections = 6
max smbd processes = 6
deadtime = 1
socket options = TCP_NODELAY IPTOS_LOWDELAY IPTOS_THROUGHPUT SO_RCVBUF=65535 SO_SNDBUF=65535
unix charset = UTF8
display charset = UTF8
bind interfaces only = yes
stat cache = no
interfaces = 192.168.0.1/255.255.255.0
[volume1]
path = /tmp/usbdisk/volume1
browseable = yes
writable = yes
guest ok = yes
create mask = 0777
directory mask = 0777
[volume9]
path = /tmp/usbdisk/volume9
browseable = yes
writable = yes
guest ok = yes
create mask = 0777
directory mask = 0777
#
5)设备挂载信息
# cat /proc/mounts
rootfs / rootfs rw 0 0
/dev/root / squashfs ro,relatime 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,relatime 0 0
none /tmp ramfs rw,relatime 0 0
none /var ramfs rw,relatime 0 0
none /proc/bus/usb usbfs rw,relatime 0 0
/tmp/dev/sda1 /tmp/usbdisk/volume1 vfat rw,noatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=cp850,iocharset=utf8,shortname=mixed,errors=remount-ro 0 0
/tmp/dev/sdb1 /tmp/usbdisk/volume9 vfat rw,noatime,fmask=0000,dmask=0000,allow_utime=0022,codepage=cp850,iocharset=utf8,shortname=mixed,errors=remount-ro 0 0
通过函数:
setmntent() 是打开包含挂载点项目的文件, 其中的 filename 参数是要打开的文件名, type 参数就像 fopen() 的第二个参数, 代表只读、只写, 或读写皆可的存取模式 。返回FILE*。
getmntent() 则是循序读取整个档案,传回指向 static struct mntent 结构的指针,结构中会填入适当的值。 
6)考虑向后兼容多个SD卡,设置了单个和两个SD卡接口的枚举,相应地设置volume值的范围
7)插入USB设备,发现smbd进程不能成功运行
跟踪串口输出信息:
QQ Debug: pidfile_create 6233 ERROR: smbd : fcntl lock of file /tmp/samba/var/locks/smbd.pid failed. Error was Permission denied
系统调用函数fcntl错误
  #include <fcntl.h>
  int fcntl(int fields, int cmd,.../*int arg*/); //若成功则依赖于cmd,若出错则返回-1
 
   第三个参数总是一个整数,与上面所示函数原型中的注释部分相对应。但是在作为记录锁用时,第三个参数则是指向一个结构的指针。
   fcntl函数有5种功能:
     1.复制一个现有的描述符(cmd=F_DUPFD).
     2.获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).
     3.获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
     4.获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).
     5.获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW).


 命令字(cmd)F_GETFL和F_SETFL的标志如下面的描述:
            O_NONBLOCK            非阻塞I/O;如果read(2)调用没有可读取的数据,或者如果write(2)操作将阻塞,read或write调用返回-1和EAGAIN错误
            O_APPEND                    强制每次写(write)操作都添加在文件大的末尾,相当于open(2)的O_APPEND标志
            O_DIRECT                    最小化或去掉reading和writing的缓存影响.系统将企图 避免缓存你的读或写的数据.如果不能够避免缓存,那么它将最小化已经被缓存了的数据造成的影响.如果这个标志用的不够好,将大大的降低性能
            O_ASYNC                    当I/O可用的时候,允许SIGIO信号发送到进程组,例如:当有数据可以读的时候


在修改文件描述符标志或文件状态标志时必须谨慎,先要取得现在的标志值,然后按照希望修改它,最后设置新标志值。不能只是执行F_SETFD或F_SETFL命令,这样会关闭以前设置的标志位。


fcntl的返回值 与命令有关。如果出错,所有命令都返回-1,如果成功则返回某个其他值。下列三个命令有特定返回值:F_DUPFD,F_GETFD,F_GETFL以及F_GETOWN。第一个返回新的文件描述符,第二个返回相应标志,最后一个返回一个正的进程ID或负的进程组ID。 
原因:kernel中要启用File Lock的API函数支持,CONFIG_FILE_LOCKING=y;


8)插入U盘,产生3个uevent信号
QQ Debug: parseUsbSingleHotplugEvent 162 hotPlug->path = /devices/platform/rt3xxx-ehci/usb1/1-1/1-1:1.0/host5/scsi_host/host5, hotPlug->subsystem = scsi_host;
QQ Debug: parseUsbSingleHotplugEvent 162 hotPlug->path = /devices/platform/rt3xxx-ehci/usb1/1-1/usb_device/usbdev1.7, hotPlug->subsystem = usb_device;
QQ Debug: parseUsbSingleHotplugEvent 162 hotPlug->path = /devices/platform/rt3xxx-ehci/usb1/1-1/1-1:1.0/host5/target5:0:0/5:0:0:0/block/sda/sda1, hotPlug->subsystem = block;
只处理第三个,因为到了第三个,才有分区信息显示。


本主题提供 SCSI 磁盘连通性概述。


Linux SCSI 子系统由三层组成:
上层包括特定的设备类型驱动程序(最接近用户空间的驱动程序,例如磁盘驱动程序,磁带驱动程序和 CD-ROM 驱动程序)。
下层包括与硬件密切相关的驱动程序(例如 QLogic 和 Emulex 主机总线适配器(HBA)驱动程序)。
中层是将上层和下层驱动程序统一的 SCSI 核心。
根据内核分发版,这些驱动程序可能编译到内核中或构建为装入内核的模块。sd 驱动程序是 SCSI 磁盘驱动程序或块驱动程序,当其构建为模块时被命名为 sd_mod。SCSI 中间层驱动程序构建为模块时,名为 scsi_mod。
通常,在大多数分发版中,这些驱动程序都被构建为模块,并将作为 initrd 映像在引导时装入。如果引导时未装入这些驱动程序,且引导时又需要这些程序,那么应该构建一个包含这些驱动程序的 initrd 映像。对于 2.4 内核,通过修改 /etc/modules.conf 文件来完成这些工作。对于 2.6 内核,通过修改 /etc/modprobe.conf 文件和 /etc/sysconfig/kernel 文件来完成这些工作。修改了这些文件之后,需要运行 mkinitrd 命令来实现更改。


9)readdirname函数返回NULL,导致通过samba访问目录是查看不到目录下面的文件
函数OpenDir打开 . 目录,然后通过while循环调用readdirname,在里面读取.目录下的子目录和文件。
编写readdir测试函数,遍历.目录下的文件,如果将测试函数单独编译成app,下载到tmp目录中,发现是可以遍历目录的,但是如果放在samba的源码中调用这段测试代码,发现还是失败。
函数调用路径:
readdirname->OpenDir->start_dir->dptr_create->call_trans2findfirst->reply_trans2.


start_dir调用OpenDir遍历目录下的所有文件,保存在Connections.dirptr中。
call_trans2findfirst调用get_lanman2_dir_entry访问dirptr中的文件


10)在demo板上测试过相同的程序,发现是可以的,但是在开发上,发现当u盘里面的文件在重新插拔的时候会删除掉,现在现象是两个,一个是文件被删除,二是文件创建后刷新就找不到了,先解决第一个问题,可能是在tphotplug中




11)smb rpm的调试
nasSetShareList 设置smb.conf配置文件


12)ftp服务器在收到客户端的请求后,进程退出,抓包发现三次握手后,服务器发出了FIN包。
原因在函数hash_add_entry中查找条目的hash表,发现出现重复的hash条目,导致程序调用了die函数,
hash_add_entry(struct hash* p_hash, void* p_key, void* p_value)
{
  struct hash_node** p_bucket;
  struct hash_node* p_new_node;
  
  if (hash_lookup_entry(p_hash, p_key))
  {
    bug("duplicate hash key");
  }
...
}
查找使用的key是子进程的pid,但是出现了两次查找使用的子进程PID是相同的pid,所以找到了重复的entry。
问题出现在:vsf_sysutil_fork_isolate_failok
这个函数里面使用了syscall的系统调用函数,一版来说,syscall系统调用每个调用都有一个系统调用号,这个调用宏定义在
..\toolchain\buildroot-gcc342\include\bits\syscalls.h文件中
而具体的宏的值定义在
..\toolchain\buildroot-gcc342\include\bits\sysnum.h


通过和demo板的比较,发现demo板 上的输入日志是
vsf_sysutil_fork_isolate_failok 1294 :cloneflags_work=1
vsf_sysutil_fork_isolate_failok 1300 : -1 22
vsf_sysutil_fork_isolate_failok 1316 : 8086
vsf_sysutil_fork_isolate_failok 1316 : 0
vsf_standalone_main 180 8086
vsf_standalone_main 180 0


而开发板的输出日志是
vsf_sysutil_fork_isolate_failok 1294 :cloneflags_work=1
vsf_sysutil_fork_isolate_failok 1300 : 22 0
vsf_sysutil_fork_isolate_failok 1308 : 22
vsf_standalone_main 180 22
很明显,在demo板上syscall返回-1,error 等于22,而开发板上返回值是22,error是0


在代码中对ret进行修正,如果返回是22,则设置成-1,并且将errno设置成22,vsftpd可以正常启动,但是登录的时候可以连接成功,但是在函数priv_sock_get_cmd中出错了。抓包对比demo板的过程,连接成功后应该出现欢迎信息,如下:
220 Welcome to TP-LINK FTP server
USER admin
331 Please specify the password.
PASS admin


vsf_sysutil_unix_stream_socketpair 使用setsockopt创建两个socket
问题的原因是syscall中使用了参数CLONE_NETNET,但是这个参考需要kernel中的Network namespace支持,增加了这个宏就可以了。
对Network namespace的解析:
 A network namespace provides an isolated  view  of
      the  networking  stack (network device interfaces,
      IPv4 and IPv6 protocol stacks, IP routing  tables,
      firewall  rules,  the /proc/net and /sys/class/net
      directory trees, sockets, etc.).  A physical  net-
      work device can live in exactly one network names-
      pace.  A virtual network device ("veth") pair pro-
      vides  a pipe-like abstraction that can be used to
      create tunnels between network namespaces, and can
      be  used  to create a bridge to a physical network
      device in another namespace.
13.计数器重复计算的问题
14.smbd创建passwd失败
原因:在函数do_smbpasswd中调用getpwnam返回失败。getpwnam从文件/etc/passwd中读出账号,但是因为在文件系统中/etc/passwd没有做到/tmp/pwsswd的符号链接,导致文件中没有admin的账号名。
15.在挂载设备的时候需要制定挂载点的属性,一般挂载点是目录,需要制定fmask和dmask,
dmask是目录的mask,fmask是文件的mask,mask是权限掩码,由3个八进制的数字所组成, 当前访问权限去掉权限掩码所表示的权限之后, 即可产生建立文件时预设的权限。 第一位表示自己访问的权限 第二位表示同组访问的权限 第三位表示其他所有人访问的权限
网络上的资料:
移动硬盘(ntfs)的:
insmod /flash/ntfs.ko
mount -t ntfs -o nls=utf8,fmask=0000,dmask=0000 /dev/block/sda1 /flash/ntfs1
mount -t ntfs -o nls=utf8,fmask=0000,dmask=0000 /dev/block/sda5 /flash/ntfs2
mount -t ntfs -o nls=utf8,fmask=0000,dmask=0000 /dev/block/sda6 /flash/ntfs3
存为名字.sh即可
内存卡的:
#假定ntfs.ko放在/flash目录里
insmod /flash/ntfs.ko
#假定你要把ntfs分区挂载到/flash/ntfs
mkdir /flash/ntfs
#假定你要挂载的分区是TF卡第2个分区
mount -t ntfs -o nls=utf8,fmask=0000,dmask=0000 /dev/block/mmcblk0p2 /flash/ntfs
也是存为名字.sh即可.
卸载ntfs:
#先强制结束正在使用/flash/ntfs的进程
busybox fuser -km /flash/ntfs
umount /flash/ntfs
16.NTFS格式支持
SD卡使用现有的ntfs-3g命令不能进行挂载,但是如果使用kernel中的ntfs.ko在使用mount命令,可以加载。
ntfs-3g是有Tuxera支持的一个开源项目,主要为Linux 提供支持NTFS格式文件系统的驱动。
fuse实在ntfs-3g中创建的设备,这个是用户态文件系统,用于挂载ntfs文件系统的
不能挂载的原因是ntfs-3g的版本问题,使用最新版的ntfs-3g_ntfsprogs-2013.1.13可以,另外,通过加载fs/ntfs张的
ntfs.ko,然后再使用mount命令也是可以加载的。
16.NTFS格式只读
发现是样机的问题,#10样机不能写入,但是#1样机可以,后来新到的样机也可以,坑爹啊

猜你喜欢

转载自blog.csdn.net/vickytong1018/article/details/79299808
今日推荐