สวัสดีครับทุกๆท่าน ผมเพิ่งจะมาโพสที่นี่ครั้งแรกๆเลยครับ ยินดีที่ได้รู้จักทุกท่าน

ด้วยความอยากลองทำ rom ของตัวเอง ที่ไม่ซ้ำใครดูซักที บวกกับเป็นงานที่มหาวิทยาลัยด้วยเลยลองไปขุดคุ้ยวิธีการแบบง่ายๆมา แล้วก็อยากจะแบ่งปันหน่อยครับ
(ทำบน HTC Hero แต่จริงๆมันก็ใช้ได้หลายรุ่นนะครับ เอาเป็นว่าเป็น guide ง่ายๆแล้วกันนะ)

ขอบคุณ @eRobot จาก พีดีเอ และ @pj จาก DroidSans ด้วยนะครับ

อันนี้ผมเขียนเอง ผิดพลาดยังไง ขอโทษด้วยนะครับ

ทำอะไรบ้าง, เพื่อ?:

GoLauncherEX -> default(ADWLauncher)

ในความคิดผม GoLauncherEX ดีกว่า ADWLauncher หลายอย่าง เช่น มี task manager, uninstaller ในตัว เราจึงไม่ต้องเปลืองเนื้อที่ในเครื่องสำหรับ app พวกนี้อีก และมันก็มี free widget ให้เลือกใช้เยอะมาก ในขณะที่ launcher บางตัวต้องจ่ายเงินซื้อเอา แต่ที่สำคัญที่สุดคือ “effect มันลื่นมาก” แถมยังกิน ram น้อยด้วย

MIUI music player -> default(Music)

MIUI(อ่านว่า มี-ยู-ไอ) เป็น rom ของจีนที่ดังมากๆ แล้วก็มีให้ใช้ได้ในเครื่องรุ่นใหม่ๆ เกือบหมด แต่ที่ผมชอบที่สุดจาก MIUI ก็คือ music player ของมัน เพราะว่ามันเขย่าเครื่องเพื่อเปลี่ยนแพลงแบบ iPhone ได้ แถมยังจัดการ playlist ได้ในตัวเลย

Gallery2D -> default(Gallery3D)

เราจะไม่ใช้ Gallery3D ใน how-to นี้นะครับ เพราะว่ามันกินเครื่องมาก ด้วย effect ต่างๆของมัน ที่ไม่ได้ช่วยให้เราใช้งานได้ง่ายขึ้นเลยแต่กันทำให้เครื่องของเราช้าลง กว่าจะโหลดภาพมาได้ ก็ต้องรอแล้วรออีก เสียเวลาครับ เอาตัวเก่ามาลงดีกว่า ชื่อว่า Gallery2D ครับ ทำอะไรได้เหมือนๆกันจะต่างกันก็แค่ไม่มี effect หวือหวาครับ

DroidSansThaiKeyboard -> default

ของดัง ของดีครับ ส่วนใหญ่ custom rom ไม่ค่อยเอา keyboard ภาษาไทยติดมาให้เท่าไหร่ แต่ไหนๆ ก็ได้มีโอกาสแต่ง rom เองใช้เอง ก็ขอให้มันมีมาตั้งแต่ลงครั้งแรกเลยดีกว่า

CPU 19,710 smartassV2 -> default(264, 518)

Kernel ที่ผมใช้คือ flykernel-13 ครับ ผ่านมาหลายรุ่นแล้วแต่ก็ยังไม่เคยทำให้ผิดหวังเลย เราจะทำการ overclock มันตั้งแต่ยังไม่ได้ flash rom เลยครับ โดยความเร็วที่ผมเลือกจะเป็น 19-710 MHz. และใช้ CPU governor เป็น smartassV2 ซึ่งเจ้าตัว smartassV2 มันดีกว่า ondemand หรือ ค่าแบบอื่น ตรงที่มันไมไ่ด้ทำงานที่ ความเร็วสูงสุด หรือต่ำสุดตลอดครับ มันจะมีค่า ideal frequency ของมันเอง 2 ชุด สำหรับตอนที่เปิดหน้าจอ และปิดหน้าจอ ซึ่งเจ้าของ flykernel ตั้งค่ามาให้เราแล้ว คือ 518 MHz. เมื่อเปิดจอ และ 352 MHz. ตอนที่ปิดหน้าจอครับ ตรงจุดนี้ผมใช้ประโยชน์จาก smartassV2 เยอะอยู่โดยการให้ค่า min-max ของ frequency เกินจาก ideal ไปพอสมควร เพราะเมื่อ CPU ทำงานที ideal frequency แล้วทำงานไม่หนักพอ มันจะปรับลดลงมาที่ min-freq ครับ

Minimum free memory optimization

ปกติ Android จะทำการล้างและเรียกคืน ram อยู่ตลอดเวลาอยู่แล้วนะครับ เพียงแต่ว่า บางที มันเรียกคืนช้าไปหน่อย พอเราจะใช้งาน เลยต้องเสียเวลาไปจัดการส่วนนี้ ซึ่งมันแก้ไขไม่ได้ครับเป็นที่ตัว OS แต่สิ่งที่เราทำได้คือแก้ไขค่าต่ำที่สุดก่อนที่ Android จะทำการเรียกคืน ram ครับ ซึ่ง HTC Hero ของเราเนี่ย มันก็ไม่ได้มี ram เหลือเฟือเหมือน Android phone รุ่นใหม่ๆนะครับ ดังนั้นพวก background app หรือพวกโปรแกรมที่ค้างๆอยู่ใน ram เนี่ย มันควรูกจัดการตั้งแต่เนิ่นๆเลย ก็เลยตั้งค่านี้ไม่มันสูงๆหน่อยๆ แล้วจะกล่าวต่อไปครับ

เริ่มกันเลยครับ

Prepare ingredients

Base rom หรือว่า rom เริ่มต้นครับ ของผมใช้ Elelinux-7.1.0-RC1-Hero-v3.5-Light

Android SDK เพราะเราอาจจะต้องใช้ adb ครับ

dsixda Android kitchen ตัวสำคัญเลยครับ ไม่มีตัวนี้ ชีวิตลำบาก

Package อื่นๆ เช่น .apk application และ kernel ถ้าต้องการเปลี่ยน kernel นะครับ

set up the kitchen

ไป download dsixda kitchen จาก link นี้เลยครับ: http://forum.xda-developers.com/showthread.php?t=633246 (ถึงแม้เจ้าของ(dsixda) เขาจะเลิกทำแล้วแต่ว่ายังมีนักพัฒนาเอา kitchen ตัวนี้ไปใช้อยู่อีกมากครับ เพราะงั้น น่าจะมีคนทำต่ออยู่แล้ว และที่สำคัญคือยังไม่เห็น kitchen ตัวไหนใช้งานง่ายกว่านี้ครับ)

ดูตามวีธีการติตั้งนี้เลยครับ รองรับทั้ง windows, linux และ mac ครับ: http://forum.xda-developers.com/showpost.php?p=5626300&postcount=3

Find your base rom

เราต้องมาเตรียมวัตถุดิบก่อนทำอาหารกันก่อนนะครับ และสิ่งที่สำคัญที่สุดก็คือ base rom ครับ มันคือ rom เริ่มต้นของเรานั่นเอง ผมแนะนำว่าหา custom rom ซักตัวมาเป็น base rom นะครับ แล้วชีวิตจะง่ายขึ้นเยอะเลย แต่ถ้าหาไม่ได้จริงๆ kitchen ตัวนี้ก็รองรับ rom หลายแบบครั้บทั้ง official rom และ nandroid backup ก็รับครับ ซึ่งวิธีการนำ rom เข้ามาใน kitchen อยู่ในวิธี setup ด้านล่างๆของกระทู้หน่อยนะครับ (http://forum.xda-developers.com/showpost.php?p=5626300&postcount=3)

Extract the base rom

หลังจากนำ base rom เข้ามาใน kitchen แล้ว เราก็จะแตก zip ออกมา ขั้นตอนดังนี้ครับ
เปิด terminal ขึ้นมาแล้วให้เข้าไปที่ kitchen image ที่เราทำไว้ครับ ใช้คำสั่ง
cd /Volumes/kitchen
จากนั้น ใช้คำสั่ง
./menu
เพื่อเริ่มการทำงานของ kitchen แล้วจะเจอหน้าจอแบบด้านล่างนี้นะครับ

ใส่เลข 1 ลงไป แล้วกด enter ครับจากนั้น kitchen จะมีคำถามขึ้นมาเกี่ยวกับการ setup WORKING folder นะครับ ให้ทำตาม instruction ที่ขึ้นมานะครับขั้นตอนต่างๆมี default ของมันอยู่ ถ้าไม่รู้ว่าจะเลือกอันไหนก็ default ไปได้เลยครับ จากนั้นเราจะได้ folder ชื่อ WORKING_*****_***** ขึ้นมา ซึ่งในนี้คือ rom ของเราครับ ถ้าจะปรับแต่งก็จะทำในนี้ทั้งหมด

Add more applications

เรามี 2 ทางเลือกครับ สำรับการเพิ่ม app ลงไปใน rom ตั้งแต่ก่อนติดตั้งนั่นคือ เพิ่มเป็น system application(ไม่สามารถ uninstall ออกได้ ต้องใช้ titanium backup เอา root access ไป uninstall) และ user application(uninstall ได้ทันที)

system app

ใน WORKING_xxx ให้เข้าไปที่ system > app ในนั้นจะมี file .apk อยู่หลายตัว ถ้าสังเกตุดูจะเห็นว่าชื่อมันคุ้นๆ เพราะว่ามันคือ application พื้นฐาน ทั้ง Settings.apk, Calendar.apk แล้วก็อีกหลายตัวเลยครับ

ลบ .apk ที่ไม่ต้องการให้มันอยู่ใน rom ออกไปครับ (ระวังด้วยนะครับ บางตัวมันสำคัญ ลบเฉพาะตัวที่แน่ใจว่ารู้จักมันจริงๆ)

copy .apk จากที่อื่นมาใส่ในนี้ครับ

ถ้าผมจะเพิ่ม GoLauncherEX มาใช้ ผมก็จะเข้าไปที่ WORKING_xxx > system > app แล้วลบไฟล์ชื่อว่า Launcher2.apk(มันคือ default launcher ที่ติดมากับ base rom ที่ผมใช้) จากนั้นนำ GoLaunherEX.apk มาใส่ในนี้ก็เรียบร้อยแล้วครับ (วิธีหาโปรแกรม ก็ google เอานะครับ)

user app

เปิด kitchen ขึ้นมาที่หน้า menu หลักครับ

ใส่เลข 0 เพื่อเข้าไปที่ Advanced option ครับ

ใส่เลข 13 เพื่อ enable /data/app ครับ

ทำตามขั้นตอนของ system app เลยครับ แต่ว่าเปลี่ยน Path เป็น

WORKING_xxx > data > app แทนครับ

Minfree memory scripting

มี application ใน android market หลายตัวนะครับ ที่จัดการกับส่วนนี้ แต่ในเมื่อเราต้องการทำ rom มันก็ควรจะถูกจัดการก่อนที่จะมีการนำ rom ไป flash ใช้งาน อาจจะยุ่งยากซักหน่อยนะครับ แต่คุ้มค่าแน่นอน
kitchen มี function นี้มาให้แล้วครับ แต่เหมือนว่ามันจะยังพังๆอยู่ซักหน่อย เพราะว่าเมื่อ restart โทรศัพท์ของเราปุ๊ป ค่าที่เซ็ตไว้มันจะกลับไปเป็นค่า default ทันทีเลย เพราะงั้น ต้องเขียน script เอาครับ เพื่อให้ค่าต่างๆกลับมาเป็นค่าที่เราต้องการทุกครั้งที่มีการ reboot เครื่อง
โดยจุดที่เราต้องไปเพิ่ม script นี้คือ system/etc/init.d/02memcputweak ถ้าไม่มี file 02memcputeak ให้สร้างขึ้นมาได้เลยนะครับ
ขอบคุณ script จาก Juwe11 จาก XDA มาใช้เป็นค่าเริ่มต้นของ minfree memory ครับ (http://forum.xda-developers.com/showthread.php?t=1111145) จาก script ใน link จะได้ว่า

————————————————————————————————————————
#!/system/bin/sh
# Copyright© 2011 Juwe11
# 13.8.2011 Updated VM values – Thanks to [Kalis] for help
# 18.8.2011 Added oom_adj values
# 19.9.2011 Updated VM and LMK values

if [ -e /sys/module/lowmemorykiller/parameters/adj ]; then
echo “0,1,2,4,6,15” > /sys/module/lowmemorykiller/parameters/adj
fi

if [ -e /sys/module/lowmemorykiller/parameters/minfree ]; then
echo “2560,4096,5632,10240,11776,14848” > /sys/module/lowmemorykiller/parameters/minfree
fi

if [ -e /proc/sys/vm/swappiness ]; then
echo “20” > /proc/sys/vm/swappiness
fi

if [ -e /proc/sys/vm/vfs_cache_pressure ]; then
echo “70” > /proc/sys/vm/vfs_cache_pressure
fi

if [ -e /proc/sys/vm/dirty_expire_centisecs ]; then
echo “3000” > /proc/sys/vm/dirty_expire_centisecs
fi

if [ -e /proc/sys/vm/dirty_writeback_centisecs ]; then
echo “500” > /proc/sys/vm/dirty_writeback_centisecs
fi

if [ -e /proc/sys/vm/dirty_ratio ]; then
echo “15” > /proc/sys/vm/dirty_ratio
fi

if [ -e /proc/sys/vm/dirty_background_ratio ]; then
echo “3” > /proc/sys/vm/dirty_background_ratio
fi
————————————————————————————————————————

ให้เราดูที่ script ส่วนด้านล่างนี้นะครับ

if [ -e /sys/module/lowmemorykiller/parameters/minfree ]; then
echo “2560,4096,5632,10240,11776,14848” > /sys/module/lowmemorykiller/parameters/minfree
fi

จะเห็นว่ามีตัวเลขอยู่ 6 ชุดด้วยกัน ซึ่งแต่ละชุดจะทำหน้าที่ต่างๆกันดังนี้ครับ
ชุดที่ 1 : 2560 -> foreground app ; app ที่กำลังเปิดใช้งานที่หน้าจอ
ชุดที่ 2 : 4096 -> visible app ; app ที่ไม่ได้กำลังใช้งานอยู่ที่หน้าจอ แต่ยังทำงานไม่เสร็จ
ชุดที่ 3 : 5632 -> Secondary server ; service ของ OS ที่ app ต้องการใช้งาน
ชุดที่ 4 : 10240 -> hidden app ; service ที่ app อาจจะต้องการใช้งาน แต่ยังไม่ใช้
ชุดที่ 5 : 11776 -> content provider ; เป็นตัวเชื่อมให้ app กับ content
ชุดที่ 6 : 14848 -> empty app ; app ที่ค้างใน ram เผื่อว่าจะใช้อีก จะได้เปิดไวๆ

* ตัวเลขที่เห็นนี้เป็นจำนวน page ถ้าต้องการดูจำนวน MB ให้ใช้สูตร X*4/1024 เช่น จาก foreground app จะได้ 2560*4/1024 = 10 MB หมายความว่า ถ้า free ram โดยรวมของระบบ ต่ำกว่า 10MB เมื่อไหร่ ให้ kill foreground ครับ

ปัญหาต่อไป คือเราจะจัดการกับพวกมันอย่างไรดีเพื่อให้ rom ที่เราทำ มันเร็ว และ ลื่น ซึ่ง HTC Hero ไม่ได้มี memory เหลือเฟือ เหมือนอย่าง android รุ่นใหม่ๆ เพราะงั้น การที่มี application ค้างอยู่ใน ram เยอะๆ จึงไม่ใช่เรื่องดีอย่างแน่นอน ด้านล่างนี้คือ script ที่ผมแก้ไป

if [ -e /sys/module/lowmemorykiller/parameters/minfree ]; then
echo “1536,4096,4096,25000,25000,25000” > /sys/module/lowmemorykiller/parameters/minfree
fi

ชุดที่ 1 : 1536 -> foreground app ; app ที่กำลังใช้งานครับขอ ram เยอะๆ หน่อย
ชุดที่ 2 : 4096 -> visible app ; app ที่่ยังทำงานไม่เสร็จ อย่าเพิ่งไป kill ครับ
ชุดที่ 3 : 4096 -> Secondary server ; service ที่ยังต้องการใช้อยู่ครับ ปิดไม่ได้
ชุดที่ 4 : 25000 -> hidden app ; service ที่ app อาจจะใช้งาน แต่ยังไม่ใช้ เอาออกไปก่อน
ชุดที่ 5 : 25000 -> content provider ; ไมค่อยได้ใช้ content จาก app อื่นมากครับ
ชุดที่ 6 : 25000 -> empty app ; app ที่ค้างใน ram เผื่อจะใช้ ส่วนมากก็ไมไ่ด้ใช้หรอกครับ

OC memory scripting

เรายังคงทำงานกับ file 02memcputweak นะครับ หลังจากที่เราจัดการเรื่อง memory ไปแล้ว เราก็จะมาดูในเรื่องของความเร็ว และ governor ของ CPU กันต่อซึ่ง script ที่ใช้ในการ overclock CPU เป็น script ง่ายๆที่เข้าไปแก้ไข config file ของ kernel ในช่วง boot OS ดังนี้ครับ

————————————————————————————————————————
#!/system/bin/sh
#
echo 19200 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
echo 710400 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
echo smartassV2 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
chmod 0755 /system/etc/init.d/*
————————————————————————————————————————

จากที่เห็นจะเป็นการ ใส่ค่า 19200 ลงไปใน /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq คือค่า minimum frequency ครับ และใส่ค่า 710400 ลงใน /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq ก็คือ maximum frequency ครับ เมื่อเราจัดการปรับแต่งความเร็วของ CPU แล้ว เรา้ก็ต้องปรับ governor ด้วย เพื่อการทำงานที่ดูดีที่สุด ผมจึงเลือก smartassV2 ครับ โดยใส่ลงไปที่ /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor จากนั้น เราต้องทำการตั้งค่า permission ของ file ต่างๆใน init.d โดยใช้คำสั่ง chmod 0755 /system/etc/init.d/* เป็นอันเสร็จสิ้นกับ file 02memcputweak ครับ

————————————————————————————————————————
#!/system/bin/sh
#
# Copyright© 2011 Juwe11
# 13.8.2011 Updated VM values – Thanks to [Kalis] for help
# 18.8.2011 Added oom_adj values
# 19.9.2011 Updated VM and LMK values

if [ -e /sys/module/lowmemorykiller/parameters/adj ]; then
echo “0,1,2,4,6,15” > /sys/module/lowmemorykiller/parameters/adj
fi

if [ -e /sys/module/lowmemorykiller/parameters/minfree ]; then
echo “1536,4096,4096,25000,25000,25000” > /sys/module/lowmemorykiller/parameters/minfree
fi

if [ -e /proc/sys/vm/swappiness ]; then
echo “20” > /proc/sys/vm/swappiness
fi

if [ -e /proc/sys/vm/vfs_cache_pressure ]; then
echo “70” > /proc/sys/vm/vfs_cache_pressure
fi

if [ -e /proc/sys/vm/dirty_expire_centisecs ]; then
echo “3000” > /proc/sys/vm/dirty_expire_centisecs
fi

if [ -e /proc/sys/vm/dirty_writeback_centisecs ]; then
echo “500” > /proc/sys/vm/dirty_writeback_centisecs
fi

if [ -e /proc/sys/vm/dirty_ratio ]; then
echo “15” > /proc/sys/vm/dirty_ratio
fi

if [ -e /proc/sys/vm/dirty_background_ratio ]; then
echo “3” > /proc/sys/vm/dirty_background_ratio
fi

echo 19200 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
echo 710400 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
echo smartassV2 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
chmod 0755 /system/etc/init.d/*
————————————————————————————————————————

ขั้นตอนสุดท้ายเพื่อให้ script ที่เราทำถูกเรียกใช้ใน boot stage ของ Android เราต้องเขียน

service script /system/etc/init.d/02memcputweak
oneshot

ลงไปที่ file init.rc ก่อนครับ ซึ่ง init.rc จะอยู่ที่ WORKING_xxx > system > etc แล้วจะได้ file หน้าตาคล้ายๆแบบนี้มา

————————————————————————————————————————
# CyanogenMod Extras

# Compcache – handle at boot
service compcache /system/bin/handle_compcache
user root
group root
oneshot

service script /system/etc/init.d/02memcputweak
oneshot
————————————————————————————————————————

Build rom from working directory

กลับมาที่ kitchen อีกครั้งนะครับ ตอนนี้เราจะทำการ pack rom กลับไปเป็น .zip เพื่อที่เราจะได้นำไป flash เพื่อทดสอบกันต่อไป

ในหน้า main menu ของ kitchen จะมีตัวเลือกให้เรา build rom นะครับ โดยการพิมพ์ตัวเลข 99 ลงไป

เมื่อเข้ามาในการ build แล้ว ให้เลือกเป็น Interactive Mode ครับ เหมาะสำหรับผู้เริ่มต้น

จากนั้นกด enter ตลอดเลยครับ ไม่ว่าจะเป็นการ zipalign เพื่อ optimize application เราให้ใช้ ram น้อยลง หรือการเขียน updater-script ลงใน rom ตัวนี้สำคัญมากครับ เพราะเป็นตัวที่บอก recovery ว่าตอน flash ต้องทำอะไรบ้าง

เมื่อผ่านขั้นตอนทั้งหมดแล้ว เราจะได้ rom ของเราอยู่ที่ folder OUTPUT_ZIP ครับ

เอา rom ไป flash แล้วก็ทดสอบกันได้แล้วครับ