IS01 Hacking IS01でDebian動かそうとする

1/10 androidの起動プロセスについて調べる

init がinit.rcを読んで色々実行している。
init.rcの書き換え?これはやめとくandroidのinitからdebianのinitを実行することになるからなんか気持ち悪い

initを差し替えてみる。
このinitの中にdebian.imgのマウントとそのマウント先へchrootするスクリプトを仕込む作戦
これならいけるのでは? -> いくつかのandroid用デーモンを起動しておきたいので不可か?

recovery_kitのイメージファイルをベースに色々やってみる
RESULTS of split_bootimg.pl
Page size: 2048 (0x00000800)
Kernel addr: 536903680 (0x20008000)
Kernel size: 5510240 (0x00541460)
Ramdisk addr: 603979776 (0x24000000)
Ramdisk size: 2742272 (0x0029d800)
Board name:
Command line: console=ttyMSM2,115200n8 androidboot.hardware=qcom
Base Address: 0x20000000

cpioアーカイブの作成
find . | cpio -o -H newc > ../newramdisk.cpio

bootimageの作成
'/home/strobo/android/tools_linux/mkbootimg' --kernel recovery_kit.img.out-kernel --ramdisk newramdisk.cpio --cmdline 'console=ttyMSM2,115200n8 androidboot.hardware=qcom' --base 0x20000000 -o newrecovery.img

bootimageのubi化
ubinize -o new_recovery_ubi.img -p 128KiB -m 2048 -O 256 ubi.cfg

kernel config
make ARCH=arm CROSS_COMPILE=../../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi- menuconfig

kernel build
make ARCH=arm CROSS_COMPILE=../../prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-

----[ubi.cfg]----------------
[boot]
mode=ubi
image=newrecovery.img
vol_id=0
vol_size=200MiB
vol_type=dynamic
vol_name=boot
vol_flags=autoresize

まずコンソールの表示。カーネルパラメータを色々変えてみる
video=msm_fbとか? ->ダメだったorz
fbcon=rotate:3 -> これもダメ
ramconsole?
ttyMSM0とか?
init差し替え? no
tty0,115200n8 fbcon=rotate:1 fbcon=font:VGA8x8で表示されたけどなんかおかしい。スクロールが遅い、スクロール終わらない。表示内容の意味がわからん 例外っぽいかな

1/15 1/16 あきらめる

1/17 2chの過去スレにヒントとなる書き込みを発見
651:goroh_kun ◆AiupvGD4lo :2011/03/28(月) 08:32:51.03 ID:6vg6sfeM
どなたからの質問か分からないのでここで回答します。
IS01で起動時に実機にconsoleを出す方法
(1)kernelのブートパラメータいじります。mkbootimgのときにしていしているやつです。
以下のパラメータを追加すればOK
androidboot.console=tty0 fbcon=rotate:1
(2)autoexec.shに以下のコマンドを追加します。
ioctl -a 1 -d /dev/tty0 0x4b3a 0
これで起動時に画面にコマンドプロンプトが出ますので、表示中にstop等
入れてあげれば、起動前の状態でいろいろ実験できます。
以上
652:goroh_kun ◆AiupvGD4lo :2011/03/28(月) 09:44:23.46 ID:6vg6sfeM
ちなみにAndroid起動後にconsole画面と切り替えたい場合は、adbで接続後、
setconsole -v 1
で切り替えられます。
元に戻したい場合は、
setconsole -v 7
です。

1/18
LinuxのShellについて調べる。それでこのコードの意味がわかった
exec sh >/dev/tty1 2>/dev/tty1 </dev/tty1
そしてうまくconsoleが表示された!

以下まとめ
kernelをFramebuffer Console Rotationを有効にして再構築
kernelパラメータはこれがよさげ
console=ttyMSM2,115200n8 androidboot.hardware=qcom androidboot.console=tty0 fbcon=rotate:1
init.rcに追加
service /system/bin/sh /debian.sh

----[debian.sh]---------
#!/system/bin/sh
toolbox ioctl -a 1 -d /dev/tty0 0x4b3a 0
exec /system/bin/sh >/dev/tty0 2>/dev/tty0 </dev/tty0

これでとりあえずconsoleは出る。さらに操作可能、ただし一部記号入力不可

----debianのインストール方法など---------
http://www.debian.org/releases/stable/armel/apds03.html.ja
http://d.hatena.ne.jp/rattcv/20101219#p1

Todo
-まずsdcardのマウント
-debian.imgのマウントとchroot
-wifi

プロセスツリーについて
今はこんな感じ
init(android)
+ adbd
+ /system/bin/sh debian.sh -> exec /systen/bin/sh

debianのときはこうか?
init(android)
+ adbd
+ /system/bin/sh debian.sh -> exec /sbin/init(debian)
+ /bin/bash
でも/sbin/initはpid1じゃないとダメじゃないの?
じゃあこれは?
debian(new)
sh init(shell script)
+ exec /sbin/init(debian)
+adbd
+/bin/bash

1/19 それかinitからexec /sbin/initしてくれるようにソースを書き換えるという荒業もあり。serviceの再起動ができないかも?
debian関係の保存先はsdcard/debian/ にしたい
About sd card
[ http://www44.atwiki.jp/is01rebuild/pages/64.html ]
なぜかSDカードマウントできない!無理だ!

1/20 initをshスクリプトに置き換えても実行されてないっぽい -> /system/bin/busybox sh でもダメ
we can write this #!/bin/busybox sh that was referenced from GenooLinuxWiki
ShellScriptなinitが動かない
chroot /data/debian /bin/bash が動かない。chrootもできないどういうこと?
androidのinitを書き換えて最後にexec switch_root /sbin/bash するようにするとか?
initのソースの場所は/system/core/init/

1/21 毎回IS01のrecovery_wrに書き込むの時間かかるし、あまり書き換えたくないのでemulatorでテストに変更してみる
ramdiskの生成もいつもどうり
cd emuinitramfs
find . | cpio -H newc -oO ../emuinitramfs.cpio
cd ..
gzip emuinitramfs.cpio

emulatorのコマンドはこんな感じ
~/android/android-sdk-linux/tools/emulator -avd 1.6 -shell -ramdisk emuinitramfs.cpio.gz -show-kernel

でもやっぱりshellScriptなinitは実行してくれない。以下-show-kernelオプションで表示されたkernel messageの最後2行
Failed to execute /init
Kernel panic - not syncing: No init found. Try passing init= option to kernel.

動かそうとしたinitはこれ
#!/sbin/sh
/sbin/toolbox ioctl -a 1 -d /dev/tty0 0x4b3a 0
exec /sbin/sh >/dev/tty0 2>/dev/tty0 </dev/tty0
echo foo
/sbin/sh

/sbin/にshとtoolbox配置済み
shとtoolboxはemulatorで通常1.6を実行してadb pull /system/bin/sh emuinitramfs/system/bin/ で取ってきたものを使った

自前でinit作るしかないのか?

1/22 android1.6のソースを落とす
make initでinitがコンパイルされた。initの生成のためにandroid全ビルドする必要はなさそうだ
initのソースの改変がうまくいかない
execl("/sbin/sh",NULL)とか追加してもうまく動かない。Linuxシステムプログラミングには詳しくないからさっぱりわからん
なんか本買ってくるか
Debianの/sbin/initのソースも一応読んでおきたいけど、どこで読めるのかわからない

1/23 とりあえずandroidのinitを細工する方向で
新しくinitを作るのはまず無理だろう。androidのinitがいろんなライブラリと繋がってるから。うまくリンクできない。
init.rcには何も書かない。SDなどのマウント関係だけは記述しておこうかな
必要なデーモン類はdebianの/sbin/initから立ち上げるつもり
androidのinitの書き換えは相変わらず上手くいかないまま

261行あたりが実行部分みたいENVは自分で生成する必要がある
execv("/sbin/sh",NULL,ENV)で動いたらいいな -> ダメでした

initのコードをmain関数以外全部消すと以下のエラーが出る
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `do_device' 内:
system/core/init/builtins.c:433: `mtd_name_to_number' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `do_stop' 内:
system/core/init/builtins.c:329: `service_stop' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `do_restart' 内:
system/core/init/builtins.c:339: `service_stop' に対する定義されていない参照です
system/core/init/builtins.c:340: `service_start' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `do_start' 内:
system/core/init/builtins.c:319: `service_start' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `service_start_if_not_disabled' 内:
system/core/init/builtins.c:129: `service_start' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `do_mount' 内:
system/core/init/builtins.c:280: `mtd_name_to_number' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `do_export' 内:
system/core/init/builtins.c:161: `add_environment' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/builtins.o: 関数 `do_class_stop' 内:
system/core/init/builtins.c:147: `service_stop' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/property_service.o: 関数 `property_set' 内:
system/core/init/property_service.c:319: `property_changed' に対する定義されていない参照です
out/target/product/generic/obj/EXECUTABLES/init_intermediates/property_service.o: 関数 `handle_property_set_fd' 内:
system/core/init/property_service.c:375: `handle_control_message' に対する定義されていない参照です

init.cのコードは他のファイルからも参照されているようだ。init.cに必要な関数を残すか。init.cの関数を参照しているコード(builtins.c property_service.c)の方を消すか。どっちか決める。前者の方がいいかな。

このコードを904行目A N D R O I Dと表示する下あたりに追加するとキーボードからの入力文字が画面に表示された。shellは動いてないので表示されるだけ
fd = open("/dev/tty0", O_RDWR);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
その下にexecve("/sbin/sh",newargv,(char **)ENV);を書いたが画面に変化なし

1/24 LinuxKernelのソースを読んでみる
[init/main.c]780行目
static void run_init_process(char *init_filename)
{
argv_init[0] = init_filename;
kernel_execve(init_filename, argv_init, envp_init);
}
ソース見た感じだと、おそらくkernelパラメータでは引数は渡せない。init=/bin/sh boot.shみたいなことはできない

ちなみにmeego on dell streak の CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyMSM0 mem=88M"

cmdlineにroot=/dev/mtdblk0p1とか?いや無理だろ

recoverykitのソース読んで。initをcで書いてみる
init.c内部でprintkしたかったけどリンクエラーでしたprintk.c見たら大量に他のファイルをインクルードしてるから。printk動かすのは無理かも...
とにかくinit内で文字を出力したい。じゃないとデバッグすらできない
Report abuse