Category: Linux

Ubuntu for Android on XOLO X900

This post is synchronized from (click here for best display effect): https://zohead.com/archives/ubuntu-for-xolo-x900/ Lava XOLO X900 smartphone use Intel Atom Z2460 x86 CPU, so we can try to make some modifications to default Android system, then we can get a tentative Ubuntu for Android system. The important part of this is we can run x86 version Ubuntu, which is much more useful than ARM version Ubuntu (you can do nothing without source code, no proprietary software at all). Let’s see the final Ubuntu for Android effect (on Motorola LapDock 100): For now, I can run some quite useful program like: Skype, Ubuntu One, sopcast in this Ubuntu system on Android. And the most brilliant thing is we can run Ubuntu and Android system simultaneously, Ubuntu is running on another display screen, doesn’t affect Android system at all, we don’t need VNC to remote login to Ubuntu. Click here for introduction about Canonical’s Ubuntu for Android: http://www.ubuntu.com/devices/android Requirements of Canonical’s Ubuntu for Android: Dual-core Android smartphone, at least 512MB RAM; support secondary frame buffer; support USB OTG While sad point is secondary frame buffer is not enabled on XOLO X900, cause stock kernel only register a /dev/graphics/fb0 frame buffer device. But we the powerful USB OTG, so we can use USB external display adapter to provide secondary frame buffer. Devices & accessories we need: Motorola LapDock 100 (for display screen, keyboard and mouse input, quite convenient, of course you can use your own display device) DisplayLink USB display adapter USB OTG cable HDMI cable 1. Prepare x86 Ubuntu system: Cause XOLO X900 only has 16GB ROM space, and consider about speed and expansibility, you’d better use Class 10 microSD card (otherwise your Ubuntu system’s performance may not be good), and install Ubuntu in hidden microSD slot of XOLO X900. You can check […]

构建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 挂掉的后果承担责任,有任何问题欢迎提出指正哦 ^_^

Android x86对native ARM的支持

本文同步自(最佳显示效果请点击):https://zohead.com/archives/android-x86-arm-binary/ 之前入手联想 K800 这款使用 Intel x86 CPU 的手机时考虑过一个问题,就是 Android x86 对于已有的 Android 程序的兼容问题问题,特别是对于一些使用了 native ARM 代码的程序(以游戏居多),因为不可能原来所有的程序都可以及时更新来支持 x86 的 Android 手机(本来就很小众)。在我的想法中,Intel x86 环境下应该不可能直接运行 native 的 ARM 二进制代码(虚拟机那种不考虑),不过考虑到平时玩使用 native ARM 代码的游戏也不多,就没有在意。 我们先来看一个典型的使用了 native ARM library 的 Android 程序:《Bejeweled 2》,也就是大家在电脑上很熟悉的《宝石迷阵2》游戏的 Android 版本,查看 apk 安装文件里的内容,可以明显发现其使用了 ARM EABI 的动态库: 但我在 K800 上安装此游戏,完全可以正常运行并使用,只是似乎没有在 ARM Android 手机上运行的那么顺畅。 这就比较疑惑了,接下来那就进一步验证一下,将之前静态编译的一个 ARM 可执行程序拷到手机,在终端中运行,竟然也可以正常运行,我们看看这个 ARM 可执行程序的格式: 经过一番搜寻之后,发现原来 Android x86 4.0 版本之后已经开始支持对 native ARM 的仿真,这对于之前用处似乎一直不是很大的 Android x86 来说绝对可以算是相当大的进步。 联想 K800 使用的 CPU 是 Intel Atom Z2460,基于 Intel Medfield 平台,尽管 Z2460 是一款使用 x86 指令集的 CPU,但可以兼容运行大部分带有 native ARM 代码的应用,关键就是靠 Intel 并未公开发表的技术 ARM binary code translator,而且 binary translator 对于应用程序来说是透明的,一般不需要做任何特殊的改动。 在 Android x86 上 Google 修改了 dalvik 虚拟机的加载 native code 的函数(修改 libdvm,增加 libdvm_houdini.so),通过 Intel ARM to Atom binary translator 实现 JNI 调用。Android x86 中引入了 libhoudini.so 来做这件事情,通过查看 K800 的根文件系统,我们可以看到除了 /system/lib 下的标准的 x86 的动态库文件之外,新增了 /system/lib/libhoudini.so 库,另外 /system/lib/arm 目录下还有很多 ARM 版本的库文件。 下面是我在 K800 上运行一个 native ARM 程序时的进程输出: 上面看到的 /system/bin/houdini 进程即为在 Android x86 上运行的 native ARM 程序的表现形式。 从现在在 K800 手机上实际的测试情况来看,在 K800 上运行使用 native ARM 的 Android 似乎都还比较顺畅,像愤怒的小鸟就可以很顺畅的运行,这和现在 K800 用的 Android 4.0.4 ROM 也有关系,相对于不支持 native ARM 的 Android 2.3.7,游戏的兼容性是有相当大的改善的。另外很有可能 Intel Medfield 平台硬件上就有对 ARM binary translator 的加速功能。 当然这种二进制的转换必然会有性能上的损失,无法和 x86 原生程序相比,因此越来越多的 Android 程序也开始集成了 x86 版本的程序和库文件,来看看最新版本的水果忍者 apk 安装程序中的库文件列表,就可以看到 x86 版本: 有关 Android x86 运行 native ARM 程序的介绍: http://www.anandtech.com/show/5770/lava-xolo-x900-review-the-first-intel-medfield-phone/3 Android x86 下运行环境的搭建: http://www.buildroid.org/blog/?p=198

构建联想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 文件,没办法,只能自己根据当前手机 kernel 判断 K800 当前的 kernel configuration 了。 运行:egrep ‘(vmx|svm)’ /proc/cpuinfo,确定 CPU 支持 Intel VT-x 虚拟化技术,有点小兴奋。 2、准备编译环境: 接着在手机上查看 /proc/version,确定联想 K800 kernel 使用的 gcc 版本为 4.3.3,刚好与 Moto 介绍的一致。然后使用 git clone 从下面的地址得到编译 kernel 的 android x86 toolchain: https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/x86/i686-android-linux-4.4.3/ 需要注意 git 得到的代码中默认已经把 gcc 4.3.3 给移除了,不过运行 git log 可以看到之前的提交日志里是有的,那好办,运行下面命令回滚到最新可用的版本: git checkout 286506f01f8ca64d6eb0e33bafb475a5cf10ff37 终于有了编译 kernel 的正确环境了(不是完整开发环境哈)。 3、编译 kernel: Moto 提供的 kernel source 中有几个适合 Intel Medfield 平台的 config 文件,SourceForge 网站上推荐使用 i386_mfld_moto_defconfig,编译时指定 CROSS_COMPILE,但我实际编译之后的模块加载会 kernel panic。好吧,我来尝试应该是 Intel 原始推荐的 i386_mfld_defconfig 默认配置,无法编译通过,排除原因,发现 i386_mfld_defconfig 中启用的几个选项在 K800 中并没有开启,遂决定去掉,同时去掉了 Moto 特有的加密模块。 修改配置之后,能编译了,但编译到 android USB gadget 代码时又有报错,查看代码,发现 Moto 对 android USB gadget 代码做了特殊改动,好吧,这我暂时不需要修改,根据 Moto 增加的 define 修改 drivers/usb/gadget/android.c,去掉 Moto 特有的改动,尽量使代码默认 Intel 原生(看来联想对 Intel 的代码改动很少,这是个好处,嘿嘿,下面也有悲催的地方),再次开始编译。 这次终于比较顺利了,能编译到链接 kernel image 的地方了,但又有报错,这时就不管了,因为我压根就不指望这个编译出来的 zImage 能直接用在联想 K800 手机上,而且联想也没开放制作其 boot image 的工具和方法,就算 zImage 有了也不知道怎么刷到手机上。 接下来编译 kernel modules,这步比较顺利,我把 CIFS、USB Mass Storage(包括 scsi disk 支持)、usbnet、usb serial converter、tun 等需要的模块都选中,都正确编译出来了。 4、修改调试: 拿到手机上加载 cifs.ko,正常,/proc/filesystems 中已经有了 cifs,但挂载文件系统时发现 dmesg 里有 out of memory 报错,一会就 kernel panic 了。 强制重启手机,这时才发现 cifs.ko 大小有 3MB 多,明显太大,查看 config 发现默认启用了 debug kernel,Moto 的默认配置中未启用,不得不说联想真是够懒的,这个影响性能的东西竟然木有去掉。 本来想禁用 […]

framebuffer VNC客户端 fbvnc-v1.0.2

本文同步自(最佳显示效果请点击):https://zohead.com/archives/fbvnc-v1-0-2/ 由于在 Raspberry Pi 上习惯使用 framebuffer 进行普通使用的关系,在需要用 VNC 连接其它机器上,一下想到还是用 framebuffer 下的程序来实现。网上也有别人写的 framebuffer VNC 客户端程序,但普遍有些问题,有些则没有考虑在类似 Raspberry Pi 这种 ARM linux 环境下使用的情况,为此我基于已有的 fbvnc 项目重新弄了个 framebuffer 下 VNC 客户端的程序。 原有 fbvnc 项目地址:http://repo.or.cz/w/fbvnc.git 我的 fbvnc 新项目的 github 地址:https://github.com/zohead/fbvnc 现在已经更新到 1.0.2 版本,相对原始的 fbvnc 的主要改进为: 解决在 16 位及 32 位 framebuffer 下显示不正确的问题; 增加帮助信息和参数选项(fbvnc -h 查看帮助信息); 支持简单的 VNC 用户名密码验证(基于 RFB 协议的 3.3 版本); 支持将 VNC 密码加密保存到密码文件; 支持以命令行参数的形式从密码文件中读取密码,方便自动运行方式; 连接远程 VNC 主机时增加远程 VNC 服务器信息输出,方便调试; 从 VNC 服务器获取版本信息前先发送客户端版本号(3.3 版本),解决某些非常严格的 VNC 服务器(例如:droid VNC server)出现拒绝访问的问题; 连接远程 VNC 主机时检查 VNC 版本是否确定以 “RFB ” 开头,如果版本不符合要求则出错退出; 解决在 ARM linux 系统(例如:Raspberry Pi)中鼠标无法正确移动的问题; 连接和断开 VNC 服务器时增加清屏和显示/隐藏光标的处理,防止终端界面紊乱。 此程序已在 Windows/Linux/Android 等不同系统的 VNC 服务器环境下测试过,需要注意的是此 fbvnc 客户端只支持 RFB 3.3 版本的 VNC 服务器,如果使用的是比较新的 RealVNC 服务器(我测试的是最新的 RealVNC 4.6.3 版本),请在服务器设置中修改 VNC 协议版本为 3.3。 请自行到上面的 github 项目地址中检出代码进行编译安装,Raspberry Pi 系统则提供了已经编译好的版本 ^_^。 使用方式很简单,运行: fbvnc 192.168.1.xxx 如果需要密码会提示你输入,完成后就可以看到远程 VNC 主机的画面,其中 192.168.1.xxx 为 VNC 服务器的主机地址,另外也可以增加参数指定 VNC 服务器的端口号(如果不是默认的 5900 端口),运行 fbvnc -h 可以查看帮助信息。 连接上 VNC 服务器之后的操作: 快捷键 操作 Ctrl + 空格 暂停/恢复 图像更新绘制 Ctrl + Alt + C 断开连接并退出 适用于 Raspberry Pi Debian Whezzy 系统的 fbvnc 程序下载链接: http://github.com/downloads/zohead/fbvnc/fbvnc-raspberry-pi-v1.0.2.7z 此程序纯粹为我基于其它项目做个人修改使用的,其中有任何问题请提出指正哦 ^_^

使用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 个,日志参数格式为: regionsize [[no]sync]regionsize 为日志区块的大小(512 个字节的扇区为单位),可选的 sync 和 nosync 用于指定 dm-mirror 是否已经同步过。 disk 类型(磁盘): 日志保存在磁盘(块设备)中,因此可以在关机或重启之后继续之前的同步进度,当然性能比 core 类型肯定是要差一些的。#logargs 个数为 2-3 个,日志参数格式为: logdevice regionsize [[no]sync]logdevice 指定日志元数据存放在哪个块设备上,可以使用设备路径或者主从设备号形式,其它参数与 core 类型相同。 Linux 系统中 dm-mirror 具体使用步骤举例如下: 首先加载 dm-mirror 模块: modprobe dm-mirror  准备好需要同步的设备,假设是实际应用中的一种常见需求:Linux 系统盘为 /dev/sda,系统中另外有个数据盘 /dev/sdb。但由于磁盘 /dev/sdb 寿命快到了,需要将 /dev/sdb 磁盘上的数据同步到 /dev/sdc 上,/dev/sdc 的容量比 /dev/sdb 要大。先得到 /dev/sdb 和 /dev/sdc 的容量大小(以 512 个字节的扇区为单位): blockdev --getsz /dev/sdb blockdev --getsz /dev/sdc假设分别为 209715200(100G) 和 314572800(150G)。 在系统中通过文件方式产生 loop 设备用作 dm-mirror 同步存放日志元数据的设备,防止关机或重启之后同步进度丢失,1MB 的文件已完全足够保存日志元数据:dd if=/dev/zero of=meta.dat bs=1024k count=1运行完成将产生一个 1MB 大小的 meta.dat 文件。 准备 loop 设备:losetup -f 得到空闲的 loop 设备名,假设为 /dev/loop0;losetup /dev/loop0 meta.dat 装载 loop 设备。 运行 dmsetup create 命令创建 dm-mirror 设备进行同步:echo “0 209715200 mirror disk 2 /dev/loop0 16384 2 /dev/sdb 0 /dev/sdc 0 1 handle_errors” | dmsetup create mirror0运行成功之后将产生名称为 mirror0 的虚拟 dm-mirror 设备。echo 中间的字符串即为 dm-mirror 的 table 格式:209715200 为同步的大小,disk 指定元数据保存在磁盘中,/dev/loop0 为元数据设备,16384 为区块大小(这里指定为 8MB 为提高同步性能),后面的参数指定将 /dev/sdb(源设备,起始地址为 0)的数据同步到 /dev/sdc(目标设备,起始地址为 0),1 和 handle_errors 表示不忽略同步错误。 查询同步状态和进度:dmsetup status mirror0输出类似下面:mirror0: 0 209715200 mirror 2 8:16 8:32 417/12800 1 AA 3 disk 7:0 A8:16 […]

Raspberry Pi framebuffer PDF阅读器 - fbpdf

本文同步自(最佳显示效果请点击):https://zohead.com/archives/raspberry-pi-fbpdf/ 最近拷了几个 PDF 电子书到 Raspberry Pi 树莓派小主板系统上,准备小充下电,结果在 Debian Wheezy Raspbian 的 Linux X11 系统下用以前用的 xpdf 软件看 PDF 的不爽:由于 Raspberry Pi 的 CPU 是 ARMv6 700MHz 的,性能一般,而且内存只有 256MB,所以跑 Linux X11 虽然没什么问题,但老感觉看大一点的 PDF 有点拖顿。 后来装了比较小巧的 mupdf 软件(Raspbian 系统的话直接用 apt-get install mupdf 命令就可以安装)之后在 X11 环境下看 PDF 电子书似乎情况好了很多,mupdf 功能很简单,甚至都没有独立的启动方式,直接双击 PDF 文件运行,或者通过命令行方式运行,主界面也没有工具栏之类的多余东西,操作全部键盘来完成,浏览 PDF 的速度也很快,对中文支持也很好。关于 mupdf 的介绍请参考其官网:http://www.mupdf.com/。 后来想到平时用 Raspberry Pi 主要还是用命令行模式,我对 Linux X11 一向比较反感 ^_^,感觉是不是可以直接用 framebuffer 的形式看 PDF,结果还真找到一个 fbpdf 软件。 fbpdf 是基于 mupdf 的代码基础上实现的纯 framebuffer 下的 PDF 阅读器,和 mupdf 的功能基本相当,用这个可以省去 X11 和 GTK+ 等一堆臃肿的玩意,在 framebuffer 上看不仅速度快而且占用内存也小,并且可以充分利用 Raspberry Pi 上 framebuffer 的硬件加速。但不幸的是 Raspberry Pi 的 Raspbian 源中没有 fbpdf 包,看来只能自己编译了。 fbpdf 的 Git 版本库地址(可以直接用 git clone 命令弄下来哦): http://repo.or.cz/w/fbpdf.git 首先到 mupdf 官网下载 mupdf 源代码和 mupdf-thirdparty 第三方程序的源代码: http://www.mupdf.com/download/mupdf-1.1-source.tar.gz http://www.mupdf.com/download/mupdf-thirdparty.zip 需要说明的是我的编译环境是 armhf 的 Raspbian 默认开发环境。编译 mupdf 之前需要先安装 libfreetype6-dev、libjbig2dec0-dev、libjpeg8-dev 等开发软件包。mupdf 编译安装好之后会产生 fitz 库的头文件和静态库文件 libfitz.a,libfitz.a 在编译 fbpdf 时需要用到。 特别需要注意的是 mupdf 和 fbpdf 使用的是修改过的 openjpeg-1.5.0 版本的 openjpeg 库,不能直接使用 Raspbian 系统中的 libopenjpeg2 库,因此需要先编译 mupdf-thirdparty 中的 openjpeg-1.5.0 库,为了防止和 Raspbian 默认的 openjpeg 库冲突,建议将 openjpeg-1.5.0 库安装到自定义的目录(非 /usr/lib、/usr/local/lib 等系统默认使用的目录),然后编译 fbpdf 时直接使用 openjpeg-1.5.0 产生的静态库文件 libopenjpeg.a。 在 Raspberry Pi 编译 fbpdf 时会有一些小报错,需要修改下代码和 Makefile,编译 fbpdf 时由于要使用 libfitz.a 静态库,因此生成的 fbpdf 可执行文件也会比较大(我编译产生的将近 6MB)。 在 Raspbian 系统的默认 framebuffer 文本终端下运行 fbpdf /home/xxx.pdf (/home/xxx.pdf 为 PDF 文件的路径)就可以查看 PDF 文件了,你的 Raspberry Pi 在用 fbpdf 打开 PDF 时很可能会遇到这个错误直接退出:fbpdf: fbval_t doesn’t match fb depth。 简单说明下这个错误的原因: fbpdf 程序中默认使用的 framebuffer 颜色数(BPP)是 32 位的,但 Raspberry Pi 默认的 framebuffer 只使用 16 位颜色(也就是下面的 framebuffer_depth 默认为 16),这样 fbpdf 程序运行时检查 framebuffer 参数发现不匹配就会报上面的错误,我尝试过跳过这项检查可以不报错,但 PDF 文件的显示渲染效果相当差。 解决方法也是必须要有的: 注意:不建议使用此方法,建议直接使用最下面的 16 位 framebuffer 版本。 打开启动分区下的 config.txt 配置文件(路径为:/boot/config.txt),加入下面两行然后重启系统就可以解决: framebuffer_depth=32 framebuffer_ignore_alpha=1 第一行 framebuffer_depth=32 指定 Raspberry Pi 的 framebuffer 使用 32 位颜色,第二行 framebuffer_ignore_alpha=1 是在使用 32 位颜色时才需要指定的,表示忽略 ARGB 颜色中的 alpha 通道。需要说明的是即使 config.txt 配置文件中指定了使用 32 位实际上也只有 20120615 种颜色的哦,不过对使用上没有影响的。 有关 Raspberry Pi 的 config.txt 配置文件的详细说明请参考这里:http://elinux.org/RPi_config.txt。 把上面的配置文件修改好重启之后,下面是用我编译好的 fbpdf 程序查看一个 5MB 的 PDF 电子书的截图,在 Raspberry Pi 这样的微型板上速度是相当之快的: 从截图中可以看到图片和中文都是可以正常显示的哦。 framebuffer 模式下的 fbpdf 也是全部通过键盘操作,不过快捷键和 mupdf 是不同的,将常用的快捷键简单介绍如下(注意是 J、K 等单按键是区分大小写的哦),大多数快捷键都可以在前面加数字指定次数之类的(深得 VI 的精髓啊,哈哈)。具体请参考 fbpdf 代码中的 README 说明文档: 快捷键 操作 Ctrl + F 或 J 下一页(5J 跳至下面第 5 页,6J 类推) Ctrl + B 或 K […]