多线程中的Double Close与System Call Hook

同事在拿到修改后的weston相关的多线程代码中,怀疑有double close。期望我可以帮忙确定出来。 修改后的weston,我们拿到的只有一个executive elf文件,并没有source code。对于这种hook要求,一般有三种方法,但是各不相同: 修改kernel中的close system call:要求可以编译内核 wrap libc中的close():可以直接更改glibc代码,也可以使用ld的“–wrap=symbol”选项,至少要有编译后的object,因为我们需要在link的时候wrap 使用LD_PRELOAD,新建一个动态库来hook/wrap close,不需要更改内核与libc,也不需要源代码 在内核中修改System Call 因为有内核源码,因此第一种方式成为了首选。double close,一般第二次close的时候会出错,但是有的时候会错误的关闭其他线程的fd,因此我们只需要在关闭出错的时候打印出这个线程的名字、pid即可。在close system calll的实现代码中添加一行即可(文件位于fs/file.c):

在用户态Hook

Continue reading »

u-boot与linux下网卡MAC地址的更改

前言 ①假设有许多开发板,连接到了同一个路由器中,而路由器的dhcpd是根据MAC地址来分配一个固定的IP地址,那么就需要为每一个开发板设定一个不同的MAC地址从而获取不同的IP地址。 ②MAC地址是需要购买的(参考点1),在产品出厂之前,都需要给板子一个MAC地址(如果有对应的设备,例如网卡,Wifi)。且这个MAC地址在出厂后,我们并不期望被更改。 下面简述了嵌入式产品中如何保证IP地址不被更改的、以及开发过程或者生产过程如何更改MAC地址。 不被更改的方法 嵌入式中对于期望不被更改的数据,一般都是存放在无法被直接擦除或者修改的存储设备中,例如nand、eMMC、EEPROM、带保护的Nor Flash、甚至是直接写在程序中。这里说的无法被直接修改是相对内存而言的,并不是无法被修改。例如nand在修改之前,一般是需要去保护、擦除。 具体的,对于嵌入式产品而言,一般都是使用u-boot来作为bootloader,u-boot将需要的一些参数放在环境变量中,例如MAC地址就是从环境变量ethaddr中获取的。因此要保证MAC地址能够不被直接修改,那么可以将u-boot中的环境变量放在一个带有保护措施的存储器中,在需要改写的时候去除保护,改写完成后再进行保护。 u-boot启动后,在板极硬件初始化的过程中,会去初始化网卡,并获取MAC地址,这有两种情况: 在初始化的过程中会去读取MAC地址相关的环境变量 也有可能是从网卡芯片中的内置EEPROM获取MAC地址(例如SMC911x,就会有一个EEPROM存储MAC地址,上电后,会将此IP地址加载到用户可以访问的寄存器中) 调用的路径如下,具体详细的关于u-boot中eth driver的说明参考u-boot中的文档doc/drivers.net.eth:

从环境变量ethaddr获取MAC地址的实例 具体到瑞萨的Cortex-A15芯片而言,如果使用的是SoC自带的ether,那么在board_eth_init中会从环境变量中读取ethaddr环境变量,来获取MAC地址。代码文件sh-net.c。

在sh_eth_initialize(瑞萨的一款Cortex-A15 SoC自带的eth)中,会去读取ethaddr环境变量:

Continue reading »

SysV Init

RunLevel 在提及Unix System-V Init之前,让我们想一想Windows的安全模式与Android的不同启动模式。 ①在Windows启动的时候,可以按下F8,然后选择“安全模式”启动,而安全模式启动又分为带有网络和不适用网络的安全启动。显然,以不同的安全模式启动,系统在初始化时做的事情也不一样,带有网络的安全模式需要额外的初始化网卡等工作。我不了解Windows加载器(bootloader)是如何将不同启动模式的信息(bootmode)告诉Windows的,但是显然他们有约定一种方式来传递信息。或许是类似于u-boot总的bootargs,或许是在磁盘某个特殊的位置写下了对应的信息。 ②经常刷机或者对Android启动熟悉的同学,应该知道Android有几种不同的启动模式,例如:recovery mode、 fastmode。不同的启动模式作用各不相同,例如fastmode一般用于烧写Image。Android或者由Android系统更改的OS,启动模式一般都是由u-boot(bootloader)通过bootargs传递给内核,或者是在Flash中设置Flag。在Android的init程序(第一个被启动的应用程序,可能由init=来指定)启动后根据标志位或者Flasg启动不同的程序,或者使用uramdisk中不同的init.*.rc文件,从而达到不同bootmode下启动不同service,做不同设置的功能。 对于Linux/Unix系统,对于服务器,或许在它正常运行的时候不应该启动X(GUI),对于桌面Destop则需要启动X,因此不同的bootmode的需求一样存在;Unix SystemV的Init使用runlevel来决定启动不同的程序。符合LBS 4.1.0的系统不同的runlevel的约定如下表(来源于Wikipedia Runlevel词条): LSB 4.1.0 ID Name Description 0 Halt Shuts

Continue reading »

Dstream StreamLine性能分析的一个实例

前言 一个类似于Android的OS,只使用了BT机能的状态下,CPU的占有率超过20%,于是我们想看看是什么原因。本篇文章注意介绍了使用Dstream StreamLine来进行性能分析的过程和实例以及可能需要注意的地方。 StreamLine准备 使用StreamLine来分析性能主要包含以下几个过程 配置内核使得内核可以产生一些性能相关的数据,以及一些设施用以支持gator,例如:高精度的timer(hr_timer) 安装gator模块,用于系统性能数据(scheduler,event,Process)的采集以及对这些数据进行注释(annotate),例如对CP15中的PMNC(Performance Monitor Control Register)寄存器的读取与配置,对调度器数据的采集 gatord从gator内核模块中获取性能数据,并通过网络(不一定是网线)传递给Host PC中的DS-5 DS-5中的streamline对应软件模块对性能数据进行分析,以及与模块代码做出对应 对于前面的第一、第二步骤可以参考ARM官方的说明文档:ARM Streamline 编译与环境准备时候的注意点 如果使用的是adb 来让gatord传输数据到Host PC,那么需要将其中gator kernel

Continue reading »

madpaly 移植到 TQ2440 遇到问题madplay not found (2)

上一次遇到了问题,在我确定各类方式无误后, 怀疑原因可能有两个: Reason1:  我安装的Ubuntu 11.10没有需要的那个libid3tag这个文件  编译时lib3tag源码包是不会产生这个的 Reason2:  我哪里设置有问题,即在那个 ./configure …..这里设置有问题. 对于Reason1 ,我换用了一个系统 用Ubuntu 9.10,结果,一次性就搞定了. 既然如此,说明可以了,那么将其中需要的库和二进制文件放入根目录对于文件夹中去试一试. 库已经放入到/usr/lib中,而madplay则已经放入了/bin和usr/bin中 因为用的是nfs根文件系统,拷贝过去后发现是不可以的. 这个是什么原因呢? 回答一楼的问题:【Update Date

Continue reading »

madpaly 移植到 TQ2440 遇到问题 libid3tag was not found (1)

=============================================================================== 上一次构建根文件系统的时候留下了几个问题 第一是没有区分uImage和zImage 第二是对U-boot传入参数的有问题 对于第一个问题,就是需要知道什么时候用的是zImage什么时候是uImage 对于第二个问题,在u-boot中可以直接改变环境变量既可, 如TQ2440的是0选项中的NFS 选项 =============================================================================== 昨天遇到的问题: 1:     弄nfs filesystem 因为一个错误耽误了一天时间 .这个错误是在填入路径的时候没有到达底层 eg /home/tonyho/nfs/rootfs 将后面的rootfs省掉了,这样子就无法被挂载找到/bin sbin 等目录了,改了后就好了.

Continue reading »