目录
编译gpio驱动报错error: macro “__TIME__“ might prevent reproducible builds [-Werror=date-time]
UBI 不同大小的flash ubi预留的坏块大小不同(4g当2g用,同样大小的分区,4gflash上的可用容量比2g小)
设置mac报错:ififconfig: SIOCSIFFLAGS: Cannot assign requested address
利用tftpd.exe在uboot下升级时,能ping通,但是下载不了数据
uboot
设备启动时概率卡死
Ingenic T31,偶现卡死在uboot
后面发现uboot中自己开发过功能,里面有调用打印函数printf。接口调用在main_loop第一行, 此时串口和控制台有可能没有完全初始化好,有概率导致问题。
解决方法是,调整入口位置,放在读秒之前,给串口和控制台预留足够的初始化时间。
结论:Printf函数在uboot中的使用必须在串口(serial)和控制台初始化(console)后才能使用或者在屏幕上打印出来。
如果太靠前,可能会导致uboot卡死。
另外不同机器的串口或控制台初始化可能会有点时间差异,最好放在内核已经使用过printf的逻辑后面增加新代码或新功能
uboot 执行printf后异常死机问题定位_wait_66的博客-CSDN博客
内核分区坏块导致内核加载失败
大批量烧录时出现部分设备启动失败,接串口后打印如下 提示大小超过分区限制
查看bootcmd
这里写的是固定从内核分区读8MB大小的数据,如果内核分区出现坏块,那么实际可读的分区大小就会小于8MB。
查看坏块 nand bad
SigmaStar # nand bad
Device 0 bad blocks:
0c000000
SigmaStar #
查看分区起始地址
可以发现坏块刚好落在内核分区,证明我的猜想是正确的。
手动读取内核分区内容
执行 dcache on ; nand read.e 0x23000000 KERNEL ;实际上不用指定读取的长度,命令会自己计算的。
启动成功。
内核
编译gpio驱动报错error: macro “__TIME__“ might prevent reproducible builds [-Werror=date-time]
在编译gpio驱动时出现报错
查看Makefile
知识补充:
这里 -C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD) 表明然后返回到当前目录继续读入、执行当前的Makefile
查看内核Makefile
# Prohibit date/time macros, which would make the build non-deterministic
KBUILD_CFLAGS += $(call cc-option,-Werror=date-time)
这里把时间宏给禁用了,导致编译不过。
暂时注释掉这一行,重新编译即可
rmmod 驱动失败
rmmod: can't change directory to '5.10.61': No such file or directory
根据报错可知/lib/modules/下没有5.10.61这个路径,创建即可
文件系统
对文件进行写操作之后,立马断电重启,内容没有更新
问题现象:使用nand + ubifs,使用IO操作更新文件后,立马触发看门狗重启。发现文件没有更新。
问题原因:ubif挂载分区的时候使用的是 mount -t ubifs ubi0:mtd /mnt/mtd
这里补充一个知识点:
mount -t ubifs ubi0:mtd /mnt/mtd -o sync,noatime
(sync,async 同步模式,异步模式(defaults)
此选项的默认模式为异步模式。在同步模式下,内存的任何修改都会实时的同步到硬盘当中,这种模式的安全性基本属于最高,但是因为内存的数据基本一致都在变化,所以这种模式会使得程序运行变得缓慢,影响效率。而在异步模式下,虽然同步没有实时,但是现在考虑到日志文件系统的存在,所以安全性基本不用考虑,而异步模式的效率会更高,随意目前普遍使用异步模式为默认
atime(defaults),noatime 是否在读访问时更新atime)
因为默认是异步模式,所以文件实际上是没有立即落地的,此时断电或者看门狗重启就有丢失的风险。
解决方案:改成同步模式 mount -t ubifs ubi0:mtd /mnt/mtd -o sync,noatime
UBI 不同大小的flash ubi预留的坏块大小不同(4g当2g用,同样大小的分区,4gflash上的可用容量比2g小)
kernel/drivers/mtd/ubi/build.c
*这里我们使用的是整个闪存芯片的大小,而不仅仅是MTD分区大小,因为坏的擦除块的最大数量是整个设备的百分比,坏的擦除块不是公平地分布在闪存芯片上。因此,最坏的情况是,芯片的所有坏的擦除块都在我们正在连接的MTD分区中(ubi-> MTD)。
Linux 内核驱动解析 - UBI坏块预留大小 - 知乎 (zhihu.com)
(124条消息) 【NAND文件系统】UBI介绍_ubi文件系统_知否,知否的博客-CSDN博客
计算UBI剩余可用容量
(124条消息) UBI文件系统分区开销计算_ubi分区占用空间_ivansuntech的博客-CSDN博客
用户层
dos2unix
.sh去解析文件时,解析失败,cat看是正常的,但是vi进去发现后面有^M导致失败。
查看十六进制
是因为0d归位键,在板子上无法识别导致。之所以出现0d是因为,这个文件是在windows进行创建和编辑的,我们按下回车时windows下会加上0d 0a,linux下则只有0d。
针对这个问题我们可以用dos2unix去处理,这个是linux自带的一个命令,可以把文件转成unix格式的
-k的意思是保持输出文件的日期不变,由于这个命令不支持递归,所以当我们要转换目录下的所有文件时可以使用xargs, 例如find ./ -name "*" | xargs dos2unix -k
路由器重启更换网段之后导致域名解析失败
在后台修改 /etc/resolv.conf 中的配置,用户进程空间仍然存放的是老的 nameserver ,所以会导致解析失败
解决方案可以在获取域名之前调用一下res_init()
res_init() 函数的作用是读取 /etc/resolv.conf 的内容, 如 nameserver 地址、负载均衡策略、重试次数、超时时间等,并将读取的这些数据放到 static 类型的 _res_ 结构体中。
中文文件从windows拷贝到linux乱码问题
win下的默认格式一般是gbk,linux下时utf-8,因此从win下拷贝到linux服务器会出现乱码问题
可以使用 convmv 命令解决
ubuntu联网apt-get install convmv 即可安装
主要选项:
1、-f ENCODING
指定目前文件名的编码,如-f gbk
2、-t ENCODING
指定将要转换成的编码,如-f utf-8
3、-r
递归转换目录下所有文件名
4、--list
列出所有支持的编码
5、--notest
默认是只打印转换后的效果,加这个选项才真正执行转换操作。
例如:convmv -f gbk -t utf-8 ./* -r --notest, 将当前目录下的所有文件从gdk转换成utf-8
设置mac报错:ififconfig: SIOCSIFFLAGS: Cannot assign requested address
MAC 地址第二位数字必须是偶数,如果是奇数,为组播地址,只能作为目的地址,不能作为源地址
利用tftpd.exe在uboot下升级时,能ping通,但是下载不了数据
问题原因: windows 防火墙导致, 关闭windows防火墙即可
ubifs 报错
制作好的ubifs使用 flash_eraseall 和 nandwrite 擦写之后,启动时偶现报错
解决方案: 擦写之前将分区下的用户进程全部杀掉,牵扯有mount的目录 全部umount
可以使用fuser -mk /mnt/mtd 杀掉进程
代码实现参考下面:
static int force_umount(const char *p_mount_dir, unsigned int try_cnt)
{
int i = 0;
if (NULL == p_mount_dir)
{
printf("get null pointer, error!\n");
return -1;
}
char cmd_buf[256];
/* fuser -mk /mnt/mtd 只能调用1次, 否则/mnt/mtd被umount后再次调用 fuser -mk /mnt/mtd 将会杀死所有进程 */
memset(cmd_buf, 0, sizeof(cmd_buf));
sprintf(cmd_buf, "cd /; fuser -mk %s", p_mount_dir);
printf("cmd_buf=%s\n", cmd_buf);
system(cmd_buf);
memset(cmd_buf, 0, sizeof(cmd_buf));
sleep(1);
for (i = 0; i < try_cnt; i++)
{
if (0 == umount(p_mount_dir))
{
printf("%s umount success!\n", p_mount_dir);
break;
}
else
{
printf("waitting [%s] umount......\n", p_mount_dir);
}
sleep(1);
}
if (i >= try_cnt)
{
printf("after %d try, %s not umount~~~~~\n", try_cnt, p_mount_dir);
return -1;
}
return 0;
}
int main()
{
force_umount("/mnt/mtd", try_cnt);
return 0;
}