7
10
2013
4

grub2 引导 openSUSE 安装镜像

想安装 openSUSE 12.2,但是目标机器没有光驱,亦没有可用的能够容纳下 DVD 镜像的 U 盘。尝试 dd 镜像到 U 盘,报告找不到光驱还是什么的,启动失败,自动重启。 官方 Wiki 上 http://en.opensuse.org/Installation_without_CD 这个页面已经被删除。其它页面只有如何将 ISO 镜像弄到 U 盘上的说明,没有说明如何正确启动之。grub2 带内核参数install=hd:$isofile失败。这个据说只对 DVD 镜像有效。

最终,像很早之前那样阅读init脚本后,终于得出正确的启动方法:

menuentry "openSUSE 12.2 KDE LiveCD x86_64" {
    set isofile="/images/openSUSE-12.2-KDE-LiveCD-x86_64.iso"
    echo "Setup loop device..."
    loopback loop $isofile
    echo "Loading kernel..."
    linux (loop)/boot/x86_64/loader/linux isofrom=/dev/disk/by-label/4lin:$isofile
    echo "Loading initrd..."
    initrd (loop)/boot/x86_64/loader/initrd
}

其中,isofrom指定 ISO 文件所在的设备和路径,以冒号分隔。如果没有写对的话,将得到Failed to find MBR identifier !错误。

2013年12月22日更新:对于 openSUSE 13.1,其引导命令应该这么写:

menuentry "openSUSE 13.1 KDE Live x86_64 (zh_CN)" {
	set isofile="/images/openSUSE-13.1-KDE-Live-x86_64.iso"
	echo "Setup loop device..."
	loopback loop $isofile
	echo "Loading kernel..."
	linux (loop)/boot/x86_64/loader/linux isofrom_device=/dev/disk/by-label/4lin isofrom_system=$isofile LANG=zh_CN.UTF-8
	echo "Loading initrd..."
	initrd (loop)/boot/x86_64/loader/initrd
}
Category: Linux | Tags: linux grub grub2
7
9
2013
4

把标准输出伪装成终端

fcitx-diagnose 是 fcitx 输入法的非常优秀的诊断脚本。当输出到终端时,fcitx-diagnose 会给输出加上易于区分不同类型的消息的彩色高亮。可是,当用户把输出重定向到文件以便让其他人帮助查看时,这些高亮就没了。fcitx-diagnose 的输出很长,但如果通过管道给 less 查看的看,这些彩色也会消失。

要是 fcitx-diagnose 支持--color=always这样的选项就好了。可是 yyc 说他懒得写。getopt我只在 C 里用过,好麻烦的,所以我也懒得写。于是,我还是用我的 ptyless 好了。后来又想到,用于改变 I/O 缓冲方式的 unbuffer 和 stdbuf 应该也可以。测试结果表明,只有 unbuffer 可行,因为它是和 ptyless 一样使用伪终端的。stdbuf 则是使用 LD_PRELOAD 载入一个动态链接库的方式来设置缓冲区。

不过,既然 stdbuf 用 LD_PRELOAD 来设置缓冲区,我何不来用相同的办法改变isatty()函数的返回值呢?同时,我也学学 stdbuf,试了下__attribute__ ((constructor))指令。

#include<stdarg.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<dlfcn.h>

static int (*orig_isatty)(int) = 0;

int isatty(int fd){
  if(fd == 1){
    return 1;
  }
  return orig_isatty(fd);
}

void die(char *fmt, ...) {
  va_list args;
  va_start(args, fmt);
  vfprintf(stderr, fmt, args);
  va_end(args);
  fprintf(stderr, "\n");
  fflush(stderr);
  exit(-1);
}

__attribute__ ((constructor)) static void setup(void) {
  void *libhdl;
  char *dlerr;

  if (!(libhdl=dlopen("libc.so.6", RTLD_LAZY)))
    die("Failed to patch library calls: %s", dlerror());

  orig_isatty = dlsym(libhdl, "isatty");
  if ((dlerr=dlerror()) != NULL)
    die("Failed to patch isatty() library call: %s", dlerr);
}

然后,像 stdbuf、proxychains 那样做了个包装,不用自己手动设置 LD_PRELOAD 环境变量了。这也是我第一次使用 CMake,比 GNU 的 autotools 那套简单多了 :-)

使用方法很简单:

  1. 克隆或者下载源码
  2. 编译之
    $ mkdir -p build && cd build
    $ cmake .. # 或者安装到 /usr 下: cmake .. -DCMAKE_INSTALL_PREFIX=/usr
    $ make
    
  3. 安装之
    $ sudo make install
    $ sudo ldconfig
    
  4. 可以使用了:
    $ stdoutisatty fcitx-diagnose | less
    
Category: Linux | Tags: C代码 linux 终端 shell
5
25
2013
8

给 Python 的正则匹配限制执行时间

看到这个标题,你也许会想,这个需要限制么?不是很快就出来结果了么?

感谢 Just Great Software,虽然我没买它的产品,但是其说明书(可免费下载)中的正则教程详细地论述了这点。所以我在自己的 xmpptalk 机器人中一直不敢接受用户输入的正则表达式。引述其中的一句话:「People with little regex experience have surprising skill at coming up with exponentially complex regular expressions.」(不太懂正则的人经常能令人惊奇地写出指数级复杂度的正则。)

但很不幸,我从这里抄到的匹配网址的正则就有这种问题。在将其的修改版给我的 XMPP 机器人 Lisa 使用后,Lisa 两次被含有括号的链接搞到没响应……

所以,如果要使用用户输入的正则,我必须限制其匹配时间。方法也很简单——使用信号就可以了。当 Python 在匹配正则时如果收到信号,会转而调用信号处理器,然后再接着匹配。如果信号处理器抛出了异常,那么此异常会传播到调用正则匹配的地方,从而中断匹配操作。

示例如下:

#!/usr/bin/env python3

import re
# import regex as re
import signal

def timed_out(b, c):
  print('alarmed')
  raise RuntimeError()

signal.signal(signal.SIGALRM, timed_out)
signal.setitimer(signal.ITIMER_REAL, 0.1, 0)
s = '<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>'
r = re.compile(r'''(?:<(?:[^<>]+)*>)+b''')
try:
  r.findall(s)
except RuntimeError:
  print('time exceeded')

被注释掉的那句是调用mrab-regex-hg这个正则引擎的;它不会回溯时出这种问题。

优化下代码,写成方便使用(使用了TimeoutError,所以适用于 Python 3.3+):

import contextlib
import signal

@contextlib.contextmanager
def execution_timeout(timeout):
  def timed_out(signum, sigframe):
    raise TimeoutError

  old_hdl = signal.signal(signal.SIGALRM, timed_out)
  old_itimer = signal.setitimer(signal.ITIMER_REAL, timeout, 0)
  yield
  signal.setitimer(signal.ITIMER_REAL, *old_itimer)
  signal.signal(signal.SIGALRM, old_hdl)
Category: python | Tags: linux python 正则表达式
5
8
2013
3

编译 Android 版 zsh,以及 strace

说明一下,示例中使用的是 zsh 语法。bash 用户的话——先在电脑上用上 zsh 再考虑给手机装吧 ^_^

在网上能够找到 zshaolin 这么个包含 zsh 的 Android 包,但是它是收费的。于是,在成功编译了不少 Android 的东东后, 我决定自己编译个 zsh。

首先,把 Android NDK 放到 $PATH 里来:

path+=/opt/android-ndk/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin

其次是./configure命令。其中那个LDFLAGS的路径里有我之前编译的 ncurses。注意这里必须指定使用 ncurses 库,否则会莫名其妙地失败。使用 Android 自己的 Bionic 这个 C 库的话,就只好禁用多字节字符的支持了。

另外,ncurses 编译的时候记得禁用 C++ 支持。

LDFLAGS=-L/ldata/media/temp/android/installed_binaries/lib \
  CC='arm-linux-androideabi-gcc --sysroot=/opt/android-ndk/platforms/android-14/arch-arm' \
  ./configure --host=arm-linux-gnu --prefix=/system --with-term-lib=ncurses \
  --disable-multibyte --bindir=/system/xbin

然后做点小修改,将Src/init.cTIOCSETD相关的两处代码注释掉,不然程序会卡在这个ioctl调用上。还要把所有_mktemp函数调用换掉。在config.h中注释掉HAVE__MKTEMP宏的定义即可。

接下来是编译。完成之后修改最后一行链接代码,将 ncurses 静态链接进去:

arm-linux-androideabi-gcc --sysroot=/opt/android-ndk/platforms/android-14/arch-arm \
  -L/ldata/media/temp/android/installed_binaries/lib -rdynamic \
  -o zsh main.o `cat stamp-modobjs` -ldl -lm -lc /ldata/media/temp/android/installed_binaries/lib/libncurses.a

然后make install安装,把生成的zsh可执行文件弄到手机上任何你喜欢放可执行文件的地方,share目录弄到配置的目录里去(我这里是/system)。或者我猜设置fpath变量也行?

我第一次编译成功的 zsh 没有去掉TIOCSETDioctl调用,于是启动时卡在那里一动也不动了。要调试这种情况当然是 strace 了。但很不幸的是,strace 用到了太多 Bionic 不支持的宏定义、结构体成员等。后来我换了 zshaolin 使用的这个工具链静态链接了个 strace,终于可以用了。

最后,我编译好的二进制文件下载链接。要注意的是,此 zsh 并不支持多字节字符(如中文)(但是人家 Kindle 上的就支持呢)。

2014年3月8日更新:如果遇到任务控制(job control)时无法将后台任务切换到前台,打印出「unknown signal」的问题,可将Src/signal.c:435处的WCONTINUED改成WSTOPPED(注意不是WIFSTOPPED),即:

--- Src/signal.c
+++ Src/signal.c
@@ -432,7 +432,7 @@
          */
 #if defined(HAVE_WAIT3) || defined(HAVE_WAITPID)
 # ifdef WCONTINUED
-# define WAITFLAGS (WNOHANG|WUNTRACED|WCONTINUED)
+# define WAITFLAGS (WNOHANG|WUNTRACED|WSTOPPED)
 # else
 # define WAITFLAGS (WNOHANG|WUNTRACED)
 # endif

这个方案是我通过 strace 手机上的 busybox 的 sh 学来的 =w= 新编译的 zsh 5.0.5 可以由此下载

Category: Linux | Tags: linux Android zsh 交叉编译
5
8
2013
6

禁用 Xfce4 终端的 F1 和 F11 快捷键

我在 Xfce4 终端 0.6.1 的首选项中禁用掉了菜单快捷键,但是却没有找到禁用F1打开一个无趣的帮助窗口的方法。不过还好这个快捷键我很少用到。现在可能是经历一些升级之后,我发现F11也被拦截,变成全屏快捷键了……

解决方案与更改 Nautilus 的删除快捷键差不多,将以下内容写到~/.config/xfce4/terminal/accels.scm文件中:

(gtk_accel_path "<Actions>/terminal-window/fullscreen" "")
(gtk_accel_path "<Actions>/terminal-window/contents" "")

此方法来自 SuperUser

Category: Linux | Tags: linux gtk
4
30
2013
5

编译了点 Android 的网络命令行工具

在 Android 这个奇怪的平台想弄点 Linux-style 的东西用真不容易。网上现成的东西也比较少,这里有 stunnel、redsocks 和 iptables 等。另外 GAEProxy 里有 redsocks、iptables 和 Python 2.7,在/data/data/org.gaeproxy目录下。但它的 Python 不支持 readline,redsocks 不支持 UDP。

下边是我自己编译的几个工具和其特点(全部没有第三方库依赖):

  • redsocks:取自 git 版本,支持 UDP。其中,支持 UDP 需要search.h头和相关库函数,但是 Android 的 C 库中没有。我使用了 musl 这个 C 库中的相关文件。
  • socat:支持 readline 和 OpenSSL。openssl 这个命令行工具也作为附加文件得到了,但是感觉用处不大。
  • tcpdump:著名的网络抓包工具。没什么特别的。

编译全部使用的是 Android NDK。编译命令基本上类似于:

CC='arm-linux-androideabi-gcc --sysroot=/opt/android-ndk/platforms/android-14/arch-arm' \
  ./configure --host=arm-linux-androideabi --prefix=/ldata/media/temp/android/installed_binaries

但是不同的软件通常都会需要一些修改。比如上边说到的 redsocks。最无痛编译成功的是 LuaJIT 了,但是我这里没找到什么实际用途。另外记得把生成的可执行文件用arm-linux-androideabi-strip处理下,减小体积。

以上三个工具打包下载请点击这里备用地址)。

Category: Linux | Tags: linux 网络 Android 交叉编译
4
15
2013
8

lxc 初体验

Linux Containers 是一种系统级的虚拟化方案。其实也就是个增强型的 chroot,和 BSD 的 jail 差不多吧。

准备工作

安装 lxc 以及 bridge-utils 软件包。后者是用来建立网络的。关于对内核的要求什么的请查阅此文。虽然其内容有些过时了,但是参考价值还是很高的。当然,一般新一点的通用内核都支持的啦。

然后想好在建立的 Container 里放什么系统。比如我用的 Funtoo,安装教程在这里。但其实大部分内容没什么用的。按照这里的指示下载一个合适的 stage3 包,并解压到一个目录中。portage 的安装等后续工作就不说了。

创建一个网桥并分配 IP 地址:

$ sudo brctl addbr br0
$ sudo ifconfig br0 192.168.10.1

由于我使用的是无线网络,因此不能使用一般教程中的方法将 eth0 加到网桥中去。建立个 NAT 好了:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
sudo iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE

配置

按下边这样新建一个文本文件:

# Container 的名字
lxc.utsname = funtoo
# 网络类型。我使用的是 veth
lxc.network.type = veth
lxc.network.flags = up
# 刚刚建立的网桥名
lxc.network.link = br0
#lxc.network.hwaddr 不要乱写,会出错的!让 lxc 自己决定吧。
# IP 地址。和网桥同一网段即可
lxc.network.ipv4 = 192.168.10.2
lxc.network.name = eth0
# fstab 文件
lxc.mount = /home/lilydjwg/workspace/funtoo/funtoo_root/etc/fstab
# 新系统的根文件系统
lxc.rootfs = /home/lilydjwg/workspace/funtoo/funtoo_root
# tty 数量。如果不给出的话 lxc-console 是连不上去的
lxc.tty = 7

然后,修改 funtoo 里的配置文件啦。首先是/etc/fstab

none /home/lilydjwg/workspace/funtoo/funtoo_root/dev/pts devpts defaults 0 0
none /home/lilydjwg/workspace/funtoo/funtoo_root/proc    proc   defaults 0 0
none /home/lilydjwg/workspace/funtoo/funtoo_root/sys     sysfs  defaults 0 0
none /home/lilydjwg/workspace/funtoo/funtoo_root/dev/shm tmpfs  defaults 0 0
/home/lilydjwg/tmpfs /mnt bind 0 0

最后一行就是和主系统共享的目录啦。不过我这里没有生效 :-(

然后删掉/etc/mtab

修改/etc/inittab启动配置文件。lxc-start命令启动的那个终端会是 container 的/dev/console文件:

# TERMINALS
c1:12345:respawn:/sbin/agetty --noclear 38400 console linux
c2:2345:respawn:/sbin/agetty 38400 tty1 linux

ttyN 上的 agetty 可以留着,因为我已经分配了足够的 tty 给它们。使用lxc-console -t 3 -n funtoo就可以连上 tty3。

修改/etc/resolv.conf,配置一个 DNS 服务器。

删除/etc/runlevels/default下关于 udev 的项;udev 是不会工作的。

给新系统中的 root 设置个密码:

$ sudo chroot /path/to/funtoo/root/ /bin/bash
funtoo ~ # passwd

创建新的 container。注意创建之后那个配置文件就没有用了。lxc 会复制一份到/var/lib/lxc/funtoo/config,需要的时候可以改它。

$ sudo lxc-create -f /path/to/config/file -n funtoo

启动啦

如果我没记错的话,现在就可以启动 funtoo 啦:

$ sudo lxc-start -n funtoo

不想它占用一个终端的话就加-d选项让它在后台跑吧。

不过这时候网络还没配置好。虽然 eth0 已经有 IP 地址了,也可以和主系统相互通讯,但是路由表仍需要手动加上,不然访问不了外网的。

funtoo ~ # route add -net 0.0.0.0 gw 192.168.10.1

然后就尽情地玩儿吧 :-)

参考资料

其它链接

Category: Linux | Tags: linux lxc
3
24
2013
24

使用 Wine 运行腾讯 TM

TM 是腾讯出品的一款与 QQ 互通的即时通讯产品。用起来就是瘦过身、去过广告的 QQ。TM2009Beta3.4 是目前最新的、也是唯一能够正常使用的 TM 版本。目前最新版本为 TM2013preview1,按如下方法也可使用。TM官网。最新的 preview2 版本无法安装,请使用此地址下载 preview1 版本。

我这里使用的是 Wine 1.5.26。相比之前我运行修改版 QQ 2010 时使用的版本,此版本在 TM 输入密码时不会崩溃、没有黑影等。在线后数秒内自动变成离开状态的问题依然存在。

不像 Winhex 或者 Beyond Compare,TM / QQ 并无法在 Wine 上直接运行,需要使用 winetricks 命令安装一些东西。细节如下:

首先,因为需要使用 winetricks 安装一些东西,为干净考虑,可为 TM 设置单独的 prefix,即

$ export WINEPREFIX=$HOME/.wine4tm

我这里是 64 位的 Arch Linux,因此需要设置 Wine 使用 32 位 Windows 环境:

$ export WINEARCH=win32

注意这种情况下,不要建立未初始化的$WINEPREFIX目录。运行一下winecfg什么的,让 Wine 自己建立之。

因为是 32 位环境,所以有些库可能需要手动安装,比如 Arch 下我手动安装了以下 32 位库:

lib32-libpng lib32-libjpeg-turbo lib32-mpg123 lib32-libxml2

初次运行某个 exe 文件时,注意下终端的输出。如果其中提到某个.so文件没有找到,那么就手动安装上吧。Arch 下查询需要安装的包的方法是,使用 pkgfile 命令查询该文件名,如:

$ pkgfile libpng15.so.15
extra/libpng
multilib/lib32-libpng

lib32-开头那个即是需要安装的软件包。安装之后并不需要重新运行该 exe 文件,除非它已经导致了问题。

lib32-libpng不安装会导致部分界面显示异常,lib32-libjpeg-turbo不安装可能导致好友发送的图片无法显示。

然后使用 wine 运行 TM2009Beta3.exe 这个安装文件。同时可以开始 winetricks 相关工作。

需要使用 winetricks 安装的组件如下:

  1. riched20

    此组件将解决登陆成功后 TM 崩溃的问题。相关bug报告在此。

  2. ie6

    此组件将解决编辑消息时的崩溃。其错误消息为:

    ###!!! ABORT: Main-thread-only object used off the main thread: file /build/wine-mozilla-1.9/xpcom/base/nsCycleCollector.cpp, line 1151
    

    从 winetricks 提供的地址下载 ie6 很慢,并且有些限制。可以通过 Google 搜索「msie60.exe」得到另外的下载链接,比如这个

  3. mfc42

    此组件将解决启动时 TM 界面中的黄条警告,以及其它一些问题。

安装完毕后,在点击链接时 winebrowser 会崩溃。使用 Wine 内建的「urlmon.dll」即可。设置方法是,打开winecfg,切换到「函数库」选项卡,在「已有的函数库顶替」中编辑「urlmon.dll」项,设置其使用「内建」版本。

搞完这些,TM2009 就可以使用啦!来张高清全屏截图——

已知问题:

  • 截图仅能截取一个屏幕。快捷键仅在 Wine 程序拥有焦点时可以工作
  • 接收图片时的动画不正常
  • 输入法光标跟随无效。fcitx 输入框总是位于输入框下方(这里有补丁,据说可以修正这个问题)
  • 在 Awesome 下(特别是双显示器的扩展屏上时),鼠标拖动窗口上边缘可能导致窗口乱跑
  • 可能会卡死(线程死锁,wine 的已知 bug),特别是在打开聊天记录时
  • Awesome 下最大化等同于全屏,wibox 被遮挡
  • 数秒后会自动变成离开状态此问题已经在 Wine 1.7.6 中修复

语音和视频暂未测试。远程协助基本正常。

重要提示:TM 的截屏图片是以 JPEG 格式发送和显示的,会造成截图模糊、失真。(尽管截屏并保存的话是 PNG,从其截屏功能或者从剪贴板粘贴的、发送到会话的图片是 JPEG。)常见的可接受的截图格式只有 PNG、GIF 或 BMP。JPEG 只适合照片这种取自自然而非生成的图像。

Category: Linux | Tags: linux QQ windows wine TM 腾讯
1
21
2013
14

修改 Sony LT26i 的 boot.img

上篇记录了我给 LT26i 刷机的过程,现在该是修改它的启动代码了。

这部分内容我折腾了好久,现在把技术细节分享出来。有次我都看到有人明确表示 Sony 的 boot.img 不一样,还亲自做了新的,却没能看到修改方法,实在遗憾。

所有操作都是在 Linux 下完成的。用到的 Windows 软件 WinHex 是可以 wine 的。

解包

Sony Xperia S 使用了自己定制的格式,因此网上流传的split_bootimg.pl并不能用。Sony 提供了制作这种文件的脚本,但是没有解包的脚本。不过其格式很简单,自己写一个根本不费事:

#!/usr/bin/env python3
# vim:fileencoding=utf-8

import sys
import os
import struct

def getSegNum(f):
  f.seek(44)
  d = f.read(2)
  return struct.unpack('<H', d)[0]

def readSegInfo(f):
  d = f.read(32)
  info = struct.unpack('<LLLLLLLL', d)
  return info[4], info[1] # size, offset

def main(fname, output):
  if os.path.isdir(output):
    os.rmdir(output)
  os.mkdir(output)
  f = open(fname, 'rb')
  os.chdir(output)
  n = getSegNum(f)
  f.seek(52)
  segs = [readSegInfo(f) for i in range(n)]
  for i, seg in enumerate(segs):
    f.seek(seg[1])
    data = f.read(seg[0])
    with open(str(i), 'wb') as wf:
      wf.write(data)

if __name__ == '__main__':
  if len(sys.argv) != 3:
    print('Which file and where to extract?')
  else:
    main(*sys.argv[1:])

使用方法很简单(至少比 Sony 那个mkelf.py简单 :-)

unpackelf.py .../android/cm-9.1.0-nozomi/boot.img boot_cm

对于 CyanogenMod,解开的目标目录boot_cm下会有012三个文件。使用file命令便知,initramfs(或称 ramdisk)是1。解开它很容易:

mkdir ramdisk && cd ramdisk && gunzip < ../1 | cpio -i

对于官方 ROM 也只是多了一个叫3的文件(它的数据在boot.img的开始处)。

启动图片

很明显,logo.rle最有可能是启动图片了。可是,它是什么格式呢?Google 便有了答案。使用那里的 C 程序可将这图片有损地转成 RGB 原始数据。

5652rgb -rle < logo.rle > logo.raw

然后用 ImageMagick 的convert命令转换成常见图像格式:

convert -depth 8 -size 720x1280 rgb:logo.raw logo.png

-size那里填上自己的屏幕分辨率。不知道的话就根据屏幕比例和像素数解二元二次方程吧 ^_^ 反正要是转换出来不止一张图片肯定就不对了。

以上是显示启动图片的方法。至于生成的方法嘛,我没有需要就不弄了,直接用 Sony 原生 ROM 里的logo.rle文件替换之。

换回官方 ROM,安装 recovery

修改完启动图片,我还是不太满意 CyanogenMod 的主题啊之类的,和 Sony 的比起来太丑了。于是又刷了从网上某处找来的「索爱 LT26i 基于6.1.A.1.58最新官方ROM纯净版」。它已经 root 了,但是没有开机时按音量键的恢复模式了。于是我手动修改 initramfs,自己给它加上了。

通过比较和搜索可知,在init.semc.rc文件中,CyanogenMod 在 early-boot 的时候调用了sbin/bootrec命令。在官方 ROM 的 330 行那里加上即可。另外一个可以修改的地方是default.prop文件的ro.debuggable项,其值改成1,可以让 adb 使用 root 权限,push/pull 系统文件的时候特别方便。

然后把官方 ROM 的sbin下没有的文件从 CyanogenMod 那边复制过来即可。注意有大量软链接,可使用cp -ia来复制。我顺手把sbin/bootrec-device里的sleep 3改成只暂停一秒了。这是启动时检测按键以进入恢复模式的等待时间。同时可以看到,这个脚本会将各种指示灯点亮,有兴趣的也可以改改,比如换个指示灯颜色什么的。

打包

首先把文件们弄回 initramfs 里去:

find . | cpio -o -H newc | gzip > ../new_ram

注意这里一定要指定 cpio 的格式为newc,不然启动不了的。

本来,Sony 官方提供的mkelf.py可以用来打包,对付 CyanogenMod 的 boot.img 足够。但是官方 ROM 多出了一段,因此打包参数不一样。我直接用 WinHex 修改 boot.img 文件了。除了 initramfs 本体之外,还有三处需要修改:initramfs 的长度(两个)、下一个叫「RPM」部分的偏移位置。还好没有 checksum 之类的东西。

弄好后刷回去就可以了。不用担心刷出问题。如果导致不能开机,同时按住开机键和音量上键,直到机身震动一下,然后松开开机键,就进入 bootloader 可以刷回原来的了。

附:Reverse USB Tethering 方法

没有网上说的那么复杂,还网桥什么的,都要把电脑的网络重连 :-(

  1. 连接 USB 线,启用 USB 绑定
  2. 电脑上给新出现的usb0网络接口配置 IP,IP 段可在手机上使用ip addr命令查看rndis0网络接口的地址。比如我这里手机的 IP 是 192.168.42.129,就在电脑上执行
    ifconfig usb0 192.168.42.1
    
  3. 电脑开启 NAT 功能和 IPv4 转发
    echo 1 > /proc/sys/net/ipv4/ip_forward
    iptables -t nat -A POSTROUTING -s 192.168.42.0/24 -j MASQUERADE
    
  4. 手机上配置路由表
    ip route add default via 192.168.42.1 dev rndis0
    

    手机上的route命令很不一样,总是说参数无效,我没弄明白该怎么用,就用ip命令了。

注意这样的网络部分功能不认可导致无法使用,比如 TrackID™、VPN。

Category: Android | Tags: Android linux

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com