Category: kernel

构建Lava XOLO X900非官方kernel

本文同步自(最佳显示效果请点击):https://zohead.com/archives/xolo-x900-kernel/ 本文目标为 Lava XOLO X900 这一印度咖喱味手机,同样 Intel Atom Z2460 的芯,移植 kernel 的方法和之前的联想 K800 手机基本一致,具体请移步下面的链接: https://zohead.com/archives/k800-kernel-otg-udisk/ 经过确认 XOLO X900 默认也是 Android 4.0.4 ROM,同样 3.0.8 kernel,当然硬件会有所不同,不过 OTG U盘所需要使用的 usb-storage 模块也是和 K800 一样默认没有开启的。 基于基本相同的 kernel source,先使用 Medfield 默认的配置 i386_mfld_defconfig,发现与现有的 kernel 差距比较多,然后用 Moto 的 i386_mfld_moto_defconfig 编译出的模块加载依然 panic。没办法,硬着头皮与实际运行中 kernel 情况进行对比,发现基于默认配置 i386_mfld_defconfig 进行修改是比较好的方法,而且看得出 XOLO 相对联想还是做了一定的优化,去掉了像 CONFIG_DEBUG_KERNEL 之类的很多调试选项,默认允许了 tun 驱动等。另外声卡相关的配置不同的地方也比较多,经过最终改动和确认,编译之后,先已能成功加载并使用之前在 K800 上编译的那些模块。 XOLO X900 的内核模块和配置文件的下载地址: http://miseal.googlecode.com/files/x900-kernel-config-modules.7z 使用方法和 K800 的基本一致,只是 CIFS 文件系统的使用上有变动: insmod des_generic.ko insmod md4.ko insmod cifs.ko ASIX Electronics 的 USB 以太网卡的驱动 asix.ko 也已经更新到官方最新的版本(kernel 自带的版本无法使用)。 现已基本可以确认我改动之后的 kernel 和 X900 现有 kernel 的相似性已有 90% 或以上了,不过由于 X900 手机悲剧滴将 bootloader 给锁了,无法刷未签名的 kernel,暂时还没有太好的办法来直接替换 kernel 进行测试哦。 另外有一些需要说明的地方: XOLO X900 现有 kernel 中支持 Kineto GAN 虚拟网卡驱动(支持 VOIP 网络电话的),Moto Razr i 公开的 kernel source 中却并没有这个的支持,为此我手工增加了这个的驱动(上面下载的 kernel configuration 中也有的); 目前还有 apwr3_0、pax、sep3_7 这三个非免费开源的内核模块没有源代码,暂时也没有办法在网上找到,不过从现在来看,似乎 X900 实际运行时也未使用这三个模块。 同样我不对任何导致你的手机 panic 挂掉的后果承担责任,有任何问题欢迎提出指正哦 ^_^

构建联想K800非官方kernel支持OTG U盘

本文同步自(最佳显示效果请点击):https://zohead.com/archives/k800-kernel-otg-udisk/ 这几天专门入了个二手的联想 K800 的 Android 手机,看中的就是它是 x86 的 CPU,其采用 Intel Medfield Atom 平台,具体处理器型号为 Intel Atom Z2460,用的 Android 4.0.4 系统,具体其它配置我就不多说的。 优点: 使用 Intel x86 CPU,方便程序的移植(相对 ARM 而言); 4.5 寸的 1280 x 720 的 IPS 高清屏幕,主要分辨率够给力; 支持 USB OTG; 支持 MHL 视频输出(缺点也在这,下面再说); 耗电没想象中的那么严重; 使用的 Intel Atom Z2460 CPU 支持 EM64T 64 位指令; 使用的 Intel Atom Z2460 CPU 支持 Intel VT-x 虚拟化技术(不过这个好像在 Android 4.1 中用处才发挥出来,暂时也用不上); 很便宜。 缺点: 没有单独的 HDMI 接口,视频输出需要占用 MicroUSB,OTG 与 MHL 无法同时使用; OTG 不支持 U 盘(也是本文要解决的); 恶心的乐 Phone,联想没有公开 kernel 源代码。 上面说的缺点里,最后一条不公开 kernel source 是联想一贯悠久的恶劣传统,也是我最忍受不了的一条。 一番努力搜寻之后,我终于找到了曲线救国的神主:Motorola。对,就是他,虽然摩托似乎从来就没有开放的基因,但被 Google 收购之后,摩托在其推出的 Intel 手机 Moto RAZR i 上终于有良心了一把:公布了 Moto RAZR i 的 kernel source。由于 Moto RAZR i 与联想 K800 同样采用 Intel Medfield 平台,因此我就赌了一把其 kernel source 会有很大程度上的相似性,结果很幸运小成功了。 1、获取源码: 首先在 SourceForge 上抓取 Moto RAZR i 的 kernel source: http://sourceforge.net/projects/razr-i.motorola/files/ 一共 100 多MB,咱先解压,打开 Makefile,确定 kernel version 是 3.0.8 版本。 给联想 K800 root,装 adb 驱动,用 adb shell 连上看,运行 uname -a 查看 K800 手机的 kernel version 是 3.0.8-g37de913,啊哈,除了后缀版本一致。然后尝试读取 /proc/config.gz,无奈联想又是没有把 kernel configuration 给导出,找不到 /proc/config.gz...

使用Linux kernel dm-mirror实现设备间同步

本文同步自(最佳显示效果请点击):https://zohead.com/archives/dm-mirror-sync-device/ 在某些场合下,用户需要在 Linux 系统中实现直接的块设备同步方式,需要将一个裸设备中的内容完全同步到另一个裸设备,有时甚至需要能自定义位移和大小进行同步,这时 Linux 自带的 dm-mirror 模块很可能是比较好的实现方案。 dm-mirror 是 Linux kernel 中 device-mapper(DM)模块(device-mapper 内部称为 target)中的一个,可以实现多个块设备间的数据同步,并支持通过 dm-log 模块保存同步时的元数据信息,方便在关机和重启之后能够继续之前的进度进行同步,而且 dm-mirror 的元数据可以选择保存在内存中或者固定的块设备中。LVM 逻辑卷管理中的 pvmove 命令可以在卷组中替换物理卷,pvmove 命令正是基于 dm-mirror 模块实现的。Linux kernel 中还包含了其它的一些 device-mapper target 模块,例如 dm-linear(用于实现 LVM 逻辑卷管理)、dm-crypt(加密数据)、dm-snapshot(用于实现即时快照)等。 dm-mirror 的主要实现代码在 Linux kernel 代码树的 drivers/md/dm-raid1.c 中,dm-mirror 的日志元数据记录功能通过 dm-log 模块实现,同步的区块划分由 dm-region-hash 模块实现,底层的同步实现则由 kcopyd 来实现。kcopyd 的功能就是从一个块设备拷贝一定扇区的数据到另一个或多个块设备,kcopyd 支持异步的完成通知功能,目前主要被 dm-snapshot 和 dm-mirror 模块使用。有关 Linux kernel 中 kcopyd 的说明请参考这里:http://www.kernel.org/doc/Documentation/device-mapper/kcopyd.txt。 dm-mirror 设备的装载通过 dmsetup 命令来实现,以下说明的地址都是以扇区为单位(固定为 512 个字节),先看看 dm-mirror target 的 table 格式: start length mirror log_type #logargs logarg1 ... logargN #devs device1 offset1 ... deviceN offsetN [#features <features>] 对每个值分别说明如下: start 为虚拟设备起始扇区地址,一般固定为 0 length 为 dm-mirror 设备的大小,也就是同步的总扇区大小 mirror 值固定,表示这是一个 dm-mirror 设备 log_type 指定日志元数据类型,常用的是 core 和 disk 两种类型 #logargs 表示后面的 logarg1 ... logargN 一共有多少个 #devs 表示需要同步的设备个数,每个设备都有一个 device 值和一个 offset 值 deviceN offsetN 为每个需要同步的设备的设备路径(或者设备号)和偏移地址 #features 和 features 为可选的值,#features 表示可选项个数 如果指定了 #features,则必须为 1,且 features 必须为 handle_errors(表示 dm-mirror 会自动进行错误处理,即同步出错时自动停止同步并删除 dm-mirror 虚拟设备) 然后是 core 和 disk 两种日志元数据类型的介绍(另外有 clustered_core 和 clustered_disk 两种适用于集群的日志类型,有兴趣可以自己去了解下哦): core 类型(内存): 日志保存在内存中,关机或者重启之后会丢失,因此安全性较差,但由于元数据存放在内存中,性能相对 disk 类型来说是非常好的。#logargs 个数为 1-2...

Linux kernel学习-进程地址空间

本文同步自(如浏览不正常请点击跳转):https://zohead.com/archives/linux-kernel-learning-process-address-space/ 看完 Linux kernel block I/O 层之后来到进程地址空间管理部分,本文中的很多知识和之前的 [进程基本]、[进程调度]、[内存管理] 等章节的知识相关。 1、基础知识: Linux kernel 给每个进程提供的进程地址空间一般是 32 位或 64 位(硬件相关)的平坦地址空间,但进程是没有权限访问这段地址空间中的所有地址的,能访问的一般是很多的内存地址区间。这种内存地址区间被称为内存区域,进程可以动态添加和删除内存区域到它的地址空间中。内存区域可以有不同的权限,相关进程必须遵守这些权限,例如可读、可写、可执行等。如果进程访问的地址不在一个有效的内存区域中,或者访问时的权限不正确,kernel 将会杀掉进程并给出常见的 "Segmentation Fault" 段错误日志。 内存区域通常包括: 可执行文件的代码段,称为 text 段; 可执行文件的已初始化全局变量段,称为 data 段; 未初始化全局变量段(通常以 0 page 填充),称为 bss 段; 进程的用户空间栈(通常以 0 page 填充); 每个共享库文件的额外 text、data、bss 段,也被装入进程的地址空间; 内存映射文件; 共享内存区域; 匿名内存映射(新版本的 malloc 函数就除了 brk 之外也通过 mmap 实现); 应用程序中的堆 2、内存描述符: kernel 使用 mm_struct 内存描述符结构来表示进程的地址空间信息,它定义在 <linux/mm_types.h> 头文件中,这也是一个非常大的结构。 结构的注释中已经包含比较多的注解了哦。mmap 为地址空间的内存区域(用 vm_area_struct 结构来表示啦,也是上面的代码中)链表,mm_rb 则将其以红黑树的形式进行存储,链表形式方便遍历,红黑树形式方便查找。mm_users 为以原子变量形式保护的使用此地址空间的进程数量值(例如:如果有 4 个线程共享此地址空间,则 mm_users 值为 4),mm_count 为引用计数(所有 mm_users 等于一个引用计数),当 mm_count 值为 0 时表示没有再被使用,可以被释放。total_vm 成员表示所有内存区域的数量。 所有的 mm_struct 结构以链表的形式存在 mm_struct 的 mmlist 成员中,该链表的第一个成员就是 init 进程的 mm_struct :init_mm,该链表被 mmlist_lock 锁保护。 进程的内存描述符是在 task_struct 的 mm 成员中的。fork() 进行创建进程时调用 copy_mm 函数将父进程的内存描述符拷贝给子进程,调用 clone() 函数时如果指定 CLONE_VM 参数将使父进程和子进程地址空间共享(实际上将 mm_users 计数加 1),这种子进程就被称为线程。mm_struct 结构一般是通过 alloc_mm 宏从名为 mm_cachep 的 Slab cache 中分配。 进程退出时调用 exit_mm 函数,该函数再调用 mmput() 函数,此函数中减小地址空间的 mm_users 计数,如果 mm_users 变为 0,调用 mmdrop() 函数减小 mm_count 计数,如果 mm_count 变为 0,则最终调用 free_mm() 宏来释放内存描述符(回归到 Slab cache 中)。 另外需要说明的是 kernel 线程是没有地址空间,也就没有对应的 mm_struct(值为 NULL),kernel 线程使用之前运行的进程的内存描述符,有关 kernel 线程请参考之前的 [进程基本] 文章。 3、VMA 概念: vm_area_struct 结构即内存区域常被称为虚拟内存区域(简写为 VMA),表示的是在一个地址空间中的一个连续内存地址区间,每个内存区域是一个惟一的对象。vm_area_struct...