2012年1月22日 星期日

iPad2 iOS 5.0.1 Jailbreak @ Mac OS X

昨天看到一堆討論串,剛好我也有想研究的 app ,心一橫就跟著做把 iPad2 Wifi iOS 5.0.1 給 JB 了!為啥要心一橫?因為 JB 有風險,除此之外,還要在自己的機器執行別人寫的程式!多麼的危險啊!!


此筆記僅供個人參考,沒特別需要請不要 JB 且 JB 有風險,請自行承擔


總之,需要的檔案大概 2 個:



流程:


  1. 用 iTunes 備份 iPad2 資料(請移除備份密碼)

  2. 在 Mac OS X 上,執行 Absinthe 程式 (該程式會顯示目前 JB 進度)

  3. 當 iPad2 重新啟動後,就會多一個 Absinthe App

  4. 記得把網路設定好並且開啟 VPN 功能

  5. 點選 Absinthe App,順利的話就可以看到網頁以及進入 iPad2 重新啟動的流程

  6. 經過重新啟動後, iPad2 上頭就看到 Cydia 啦!


參考資料:





2012年1月20日 星期五

[Linux] 解決 SCIM 輸入法導致視窗失焦問題 @ Ubuntu 10.04 Desktop

預設的輸入法是用 iBUS,我忘了啥理由換成 SCIM,總之現在就是透過 SCIM 使用酷音輸入法。當初似乎是用 Synaptic 安裝的,使用 SCIM 時常常會有失焦的現象,也就是突然無法對某個視窗做事情,包括對該視窗進行操作或是滑鼠框點全選等等功能,解決方式就是透過 tab+alt 切換到其他視窗再切回來,或是動該視窗一些按鈕作動作(例如存檔),才解決了這個怪現象。


所幸網路上也有人碰到這種問題,解法就是安裝 scim-bridge-client-gtk (預設可能已經裝了)和調整 SCIM 預設的設定:


$ sudo apt-get install scim-bridge-client-gtk
$ sudo vim /etc/X11/xinit/xinput.d/scim
# GTK_IM_MODULE=xim # 舊的,把他替換掉
GTK_IM_MODULE="scim-bridge"


如此之後,重新登入視窗,顯示上有點不一樣,例如用 gedit 編輯文件時,發現打得關鍵字若串的起來會反白,大概算是更換成功吧?但反白也以點麻煩,因為我把gedit底色調黑字調白,於是又找到把這種東西弄掉的方式:


$ scim-setup
IMEngine -> Chewing -> Decorative Color -> 把一堆顏色淡(白灰色)的都改成適合的就行了(因為 chrome 輸入網址是白色的,不能用全黑 XD)


終於,忍了一個多月 SCIM 失焦問題,希望可以從此解決囉!


2012年1月19日 星期四

BeagleBoard-xM 教學筆記 - 安裝(重灌) Angstrom Demo 及 microSD 格式化筆記 @ Ubuntu 10.04

Angstram_x11_1 Angstram_x11_2


最近不順心的事還不少,一玩 beagleboard,不小心在開機時把 microSD 卡退出,導致 microSD 內建的資料爛掉,除了整個板子重開機沒反應外,把 microSD 卡插到其他 OS 讀不到。當時一度讓我有點小緊張,總不會剛拿到板子就給玩壞了 XD 所幸遲疑一下,用 Windows 7 小筆電(周邊唯一有讀卡機的設備)讀 microSD 讀不到,開始猜測問題所在處。隨後又碰到 Windows 格式化的問題,最後的解法就是跟別人借 SDCard Reader 在 Ubuntu 10.04 操作囉。


解法:找一台 Unix 機器將 microSD 重新格式化 + 安裝開機所需的檔案。除此之外,記得說明書上也以提過 beagleboard 很多接頭其實沒做太多防護,像是插錯電壓會壞的,也有人提到不太適合熱插拔,容易傷到晶片等等,需要特別留意一下。回歸正題,以下次這次解決流程:


1.確認 microSD 位置


如果 df -h 和 dmesg | tail 無法判斷的話,可以透過 Ubuntu Desktop -> [設定] -> [管理] -> [磁碟公用程式] -> [USB 週邊裝置]: 由於原先 BeagleBoard-xM 內建一張 4GB mircoSD 卡,所以查看一下就會找到,此例為 /dev/sdc


磁碟公用程式


另外提一下,之後的動作若要把 microSD 卡安全移除的話,先分別點下方儲存區(此例已點選boot區,還有另一個是Angstrom),再點選 "卸載儲存區",最後在點選右上方的 "安全移除"。


2.執行格式化


elinux.org wiki 有提到透過 mkcard.txt 來執行,作法則是 sudo sh mkcard.txt /dev/sdc,過程需要 kpartx 指令,請先用 sudo apt-get install kpartx 安裝一下。另一個步驟比較多,就是傳統使用 fdisk 的過程,請參考 elinux.org wiki,在此以 mkcard.txt script 為例:


$ wget http://www.angstrom-distribution.org/demo/beagleboard/mkcard.txt
$ sudo sh mkcard.txt /dev/sdc


1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.221714 s, 4.7 MB/s
Disk /dev/sdc doesn't contain a valid partition table
DISK SIZE - 3951034368 bytes
CYLINDERS - 480
Checking that no-one is using this disk right now ...
BLKRRPART: Device or resource busy


This disk is currently in use - repartitioning is probably a bad idea.
Umount all file systems, and swapoff all swap partitions on this disk.
Use the --no-reread flag to suppress this check.
Use the --force flag to overrule all checks.
mkfs.vfat 3.0.7 (24 Dec 2009)
umount: /dev/sdc2: not mounted
mke2fs 1.41.11 (14-Mar-2010)
Filesystem label=Angstrom
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
215568 inodes, 861485 blocks
43074 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=884998144
27 block groups
32768 blocks per group, 32768 fragments per group
7984 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200


Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done


This filesystem will be automatically checked every 23 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.


如此一來會切割出 boot 跟 Angstrom 兩個 partition 囉,只是很奇妙的重新把 microSD 插入主機,還是會找不到,所以,上面做完後,我馬上接著在做下面的:


$ sudo mkfs.msdos -F 32 /dev/sdc1 -n boot
$ sync


重新把 microSD 插入後,對 Ubuntu 10.04 來說,可在 /media/boot 和 /media/Angstrom 存取。


3.安裝所需檔案


在官網 wiki 上有提到,在 http://www.angstrom-distribution.org/demo/beagleboard/ 下載 4 個檔案,必須依序把 MLO、u-boot.bin 和 uImage 擺在 /media/boot 區,把 Angstrom-Beagleboard-demo-image-#######.tar.bz2 和 modules-#####-beagleboard.tgz 解壓縮在 /media/Angstrom 區。此以 wget 為例,建議可以先下載後,透過 cp 指令搬到 /media/boot 和 /media/Angstrom,其中要用 sudo 對 /media/Angstrom 動作。


$ mdkir ~/beagleboard
$ cd ~/beagleboard
$ wget http://www.angstrom-distribution.org/demo/beagleboard/MLO (13-Jan-2012 21:19, 42K)
$ wget http://www.angstrom-distribution.org/demo/beagleboard/uImage (13-Jan-2012 15:14, 3.2M)
$ wget http://www.angstrom-distribution.org/demo/beagleboard/u-boot.img (13-Jan-2012 21:19, 321K)
$ wget http://www.angstrom-distribution.org/demo/beagleboard/Angstrom-Beagleboard-demo-image-glibc-ipk-2011.1-beagleboard.rootfs.tar.bz2 (11-Jan-2011 11:18, 169M)
$ wget http://www.angstrom-distribution.org/demo/beagleboard/modules-3.0.17+-r115a-beagleboard.tgz (13-Jan-2012 15:14 8.9M)


$ sudo cp MLO /media/boot
$ sudo cp uImage /media/boot
$ sudo cp u-boot.img /media/boot
$ sudo tar -xv -C /media/Angstrom -f Angstrom-Beagleboard-demo-image-glibc-ipk-2011.1-beagleboard.rootfs.tar.bz2
$ sudo tar -xv -C /media/Angstrom -f modules-3.0.17+-r115a-beagleboard.tgz


其他系統微調:


為了解決系統開機時 can't create /tmp/uname: Read-only file system 等類似訊息,要更新 etc/default/udev 資料,將 DEVCACHE="/etc/dev.tar" 註解起來。


$ sudo vim /media/Angstrom/etc/default/udev
# Default for /etc/init.d/udev
# Comment this out to disable device cache
#DEVCACHE="/etc/dev.tar"


安全移除 microSD 卡


$ sync
$ sudo umount /media/boot
$ sudo umount /media/Angstrom


資料複製到 SDCard 完後,記得要卸載以及安全地移除 SDCard,因為使用 Ubuntu 10.04 的經驗告訴我,它都是卸載裝置時,才開始把資料寫進去,因此貿然抽出,就等於沒寫資料或資料不完整。


4.啟動 beagleboard-xM


先把 microSD 卡插好,再把接線接一下,準備好後,就可以開機,正常的情況時,過一會螢幕也會顯示 beagleboard logo 以及相關開機流程,最後就可以進入 OS 囉!至於要關機的話,目前若有 console 的話,我會連進去用 poweroff 關,沒 console 的部分,就得看滑鼠能不能動了 XD 此例我開機完滑鼠還未能正常工作,所以我只好直接拔電源了 XDD


beagleboard_sdcard_reading


正常啟動後,上方紅色框框處大概會不定期閃爍,類似 PC 那紅紅的讀硬碟的燈,而那兩盞燈大概是讀寫 microSD 卡,通常我用那兩個燈來判斷系統是否正常,例如有一開始沒閃燈,或是一直亮燈不動。


最後,如果需要更新板子跑其他的話,流程如下:



  1. 格式化記憶卡 ( sudo sh mkcard.txt /dev/sdX && sudo mkfs.msdos -F 32 /dev/sdX1 -n boot && sudo mkfs.ext3 /dev/sdX2 -L Angstrom )

  2. 卸除記憶卡 ( sync && unmount )

  3. 重新插入記憶卡

  4. 依序複製重要檔案到 /media/boot 和 /media/Angstrom 區

  5. 卸除記憶卡

  6. 將記憶卡插回板子,準備妥後開機即可


其他資訊:



  • 假設安裝的 OS 是 console 模式或有支援的,預設是走 RS232 115200 的,當接好線後,可以用 screen 指令開啟 terminal 來觀看


    • $ screen -U /dev/ttyUSB0 115200


  • 如果安裝 Angstrom Demo 並不順利的話,可以試試 http://narcissus.angstrom-distribution.org/ 邊,他可以依照你的設定建立好所需檔案喔


    • 純 Console 方式 (初始化要等一會,應該不用10分鐘吧)


      • machine: beagleboard

      • complexity: simple

      • environment: console

      • Additional packages:


        • Platform specific packages


          • 勾選 Bootloader Files (x-load/u-boot/scripts)




    • 走 X11 方式(視窗介面,測試結果初始化約 2.5 小時,往後開機約 2 分半鐘,關機一分鐘左右)


      • machine: beagleboard

      • complexity: simple

      • environment: X11

      • X11 Desktop: GNOME

      • Additional packages:


        • Platform specific packages


          • 勾選 Bootloader Files (x-load/u-boot/scripts)




    • 之後按 build me! 後,大概等一會兒就會看到下載連結,在把檔案下載回來處理一下即可 (此以 beagleboard-changyy.tar.gz 為例,別忘了先格式化 microSD 卡)


      • $ mkdir ~/test

      • $ cd ~/test

      • $ tar --wildcards beagleboard-changyy.tar.gz ./boot/*

      • $ cp boot/MLO-* /media/boot/MLO

      • $ cp boot/uImage-* /media/boot/uImage

      • $ cp boot/u-boot-*.bin /media/boot/u-boot.bin

      • $ sync

      • $ tar --wildcards -xvz -C /media/Angstrom -f beagleboard-changyy.tar.gz

      • $ sync




參考資料:


2012年1月18日 星期三

BeagleBoard-xM 教學筆記 - 認識週邊線材

xm-diagram


圖片來源:http://beagleboard.org/hardware-xM


第二次接觸這種硬體設備,第一次是碩班修的嵌入式課程,我記得好像也是 ARM 的 CPU。這規格還不差(CPU: ARM Cortex TM -A8, 1GHz/DSP: 800 MHz),價錢也不貴(有在工作的人都比較能負擔得起),一塊板子不用 200 塊美金,又有一堆玩 Open Source 的社群支持,覺得可以把以前一些惡搞念頭都套用上去了!更何況現在又有 Android 這火紅的 mobile os 可以利用利用。我想,定個短期目標,半年摸摸板子,搞懂如何做 Android 移植跟開機優化兩項工作好了,如果又玩得上癮,再來試試 Webkit Update 或是 OpenGL 的部分吧。


首先這只是塊板子,要與他互動還需要幾項東西:



  • 5V 2A 電源 (須留意插座孔大小, 另外也有看過 2個 USB 供電的方式)
    5V2A

  • DHMI 螢幕輸出 (可以使用 HDMI 2 DVI-D 轉接)
    HDMI2DVI-D

  • RS232 (COM Port) 轉 USB
    RS232(COM)2USB

  • USB鍵盤、滑鼠

  • microSD/SDCard 讀卡機 (以便處理記憶卡事宜)


這張板子共有 4 個 USB 孔,算是滿夠用的,不然則是可以再買一個 USB 擴充槽,記得要能夠外接電源的喔。


接著就可以看看官網提供的新手入門的文件:



2012年1月15日 星期日

在其位,謀其政

台灣大選又走過了一遭了。幾天前參加單位的活動,看著路邊插著的旗幟,才想起來這周末有大選,想著想著,好像期待發生啥事,但事實證明,無論誰選上了總統,日子還是一樣要過的,就像酒醒過後發現一項責任都沒少過。整體上我還滿不喜歡參與政治活動,政治是一種意念,只要你擁有了一方,碰到相反的另一方時,很容易起磨擦,這是無法避免的,而我喜歡自然界的定律,用亂度來達成平衡,無為而治也挺不賴的(跟碩班老師聊時,反而被說還是要多少扛起社會責任才是 XD)  網路上有很多各候選人的負面消息,我覺得都很中肯,只是這絕對不是誰當選誰下台就能解決的。


最近對生活體驗不少,記著以前總是很佩服 xxx 怎會想到 ooo 的念頭,這幾年漸漸發現,那只不過是在某個位置上就會順水推舟的看到的事情。所以啊,最重要的還是想想自己想要付出甚麼來豐富青春吧!這幾天還滿羨慕同事特地請假當志工呢!身體力行地支持心中的候選人。希望,今年也能找到一個目標,好好地衝刺一番。


2012年1月12日 星期四

Android 開發筆記 - 取得 Calendar Events 與相關筆記

最近摸到一台變形金剛,順便學習一些簡單的東西,這次目標就是取得 Calendar Events,對整個 Android 系統來說,有不少 App 都提供讓人存取的功能,在此以 Calendar 為例。


另外一提的,很多資料都是用 SQLite 格式儲存在系統裡頭,可以透過 DDMS 或其他 shell 方式瀏覽或取出 db 檔案(/data/data/com.android.providers.calendar/databases/calendar.db),接著可以用 Firefox Plugin - SQLite Manager 去查看也挺方便喔。(此動作需要root權限)


程式碼:


package tw.study.provider.calendar;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;


import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.util.Log;


public class CalendarEventProviderActivity extends Activity {
    /** Called when the activity is first created. */
    private String tagReport = "CalendarProviderActivity";
    private ArrayList<String> calendarEvents = new ArrayList<String>();
    private Hashtable<String,String> accountInfo = new Hashtable<String,String>();
    private String URI_CALENDAR_BASE = "content://com.android.calendar/calendars";
    private String URI_CALENDAR_RANGE_QUERY = "content://com.android.calendar/instances/when"; // content://com.android.calendar/instances/when/begin/end
    private SimpleDateFormat TimeFormat = new SimpleDateFormat("HH:mm");

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        if(getInfoFromCalendarDB()>0) {
                // do something via calendarEvents
        }
    }

    private int getInfoFromCalendarDB() {
        long dateRangeBegin = new Date().getTime();
        Date today = new Date(dateRangeBegin + DateUtils.DAY_IN_MILLIS);
        long dateRangeEnd=new Date(today.getYear(),today.getMonth(),today.getDate()).getTime();
        
        Log.e(tagReport,"date range from '"+dateRangeBegin +"' to '"+dateRangeEnd+"'");

        ContentResolver contentResolver = this.getContentResolver();
        Cursor accountInfoCursor = contentResolver.query(Uri.parse(URI_CALENDAR_BASE), (new String[] { "_id", "displayName", "selected", "_sync_account" }), null, null, null);
        while (accountInfoCursor.moveToNext()) {
            String _id = accountInfoCursor.getString(0);
            String displayName = accountInfoCursor.getString(1);
            String syncAccount = accountInfoCursor.getString(3);
            if( !accountInfoCursor.getString(2).equals("0") ) { // selected => enable
                accountInfo.put( syncAccount, displayName ); // use for check or display the account name
                accountInfo.put( _id, displayName );
            }
        }

        // show all columns
        String targetQuery = URI_CALENDAR_RANGE_QUERY+"/"+dateRangeBegin+"/"+dateRangeEnd;
        Log.e(tagReport,"Range Query:"+targetQuery);
        Cursor eventCursor = contentResolver.query(Uri.parse(targetQuery), null, null, null, "startDay ASC, startMinute ASC");
        for( String c : eventCursor.getColumnNames() ) 
            Log.e(tagReport,"column name:"+c);

        // add all events
        calendarEvents.clear();
        eventCursor = contentResolver.query(Uri.parse(URI_CALENDAR_RANGE_QUERY+"/"+dateRangeBegin+"/"+dateRangeEnd), new String[] { "title", "begin", "end", "calendar_id"}, null,null,"startDay ASC, startMinute ASC");
        while (eventCursor.moveToNext()) {
            String title = eventCursor.getString(0);
            Long begin = eventCursor.getLong(1);
            Long end = eventCursor.getLong(2);
            String accountId = eventCursor.getString(3);
                if( accountInfo.containsKey(accountId) ) { // skip the account which is not enabled
                calendarEvents.add("["+TimeFormat.format(new Date(begin))+"-"+TimeFormat.format(new Date(end))+"] "+title+"("+accountInfo.get(accountId)+")" );
            }
        }
        return calendarEvents.size();
    }


AndroidManifest.xml:


<uses-permission android:name="android.permission.READ_CALENDAR"/>


輸出:


date range from '1326368807153' to '1326384000000'
Range Query:content://com.android.calendar/instances/when/1326368807153/1326384000000
column name:originalEvent
column name:ownerAccount
column name:endDay
column name:visibility
column name:endMinute
column name:rrule
column name:event_id
column name:lastDate
column name:hasAlarm
column name:guestsCanModify
column name:transparency
column name:rdate
column name:exrule
column name:guestsCanSeeGuests
column name:title
column name:dtstart
column name:selected
column name:timezone
column name:_id
column name:hasAttendeeData
column name:commentsUri
column name:startDay
column name:description
column name:htmlUri
column name:end
column name:startMinute
column name:hasExtendedProperties
column name:calendar_id
column name:eventLocation
column name:dtend
column name:access_level
column name:allDay
column name:organizer
column name:originalAllDay
column name:deleted
column name:url
column name:begin
column name:originalInstanceTime
column name:duration
column name:color
column name:selfAttendeeStatus
column name:guestsCanInviteOthers
column name:exdate
column name:eventStatus
column name:eventTimezone


2012年1月6日 星期五

[Linux] 忘記密碼、更新 root 密碼的處理 @ Ubuntu 11.10

前陣子接手案子,但同事離職前程式碼沒有交接清楚,所以我就稍微黑一下前同事的桌機了 XD 提到破解密碼,過去總有一些電影場景,厲害的黑客在黑幫老大的壓力下(或正妹的服務下),只靠一台筆電跟網路就突破哪台銀行主機等等的,說真的還滿誇張的,最近則看了不可能的任務四,發現內容越來越寫實,真正的破解方式就是要到主機身邊給他本體入侵一下啦!


所以,其實忘記密碼或是想要強行入侵,只要在本機端就可以了 :P 過去我只有用過 FreeBSD 的 Single User Mode 啦,這次算是體驗一下 Ubuntu/Linux 環境:



  1. 重開機進入 Single User Mode (Recovery Mode)

  2. 用 root 將 FS 狀態改寫成可讀寫


    • $ mount -o remount-rw /


  3. 強制更換密碼


    • $ passwd your_id



這次就完成了 XD 比較可能卡住的是第一步跟第二步,像我就搞不懂怎樣進入 Single User Mode。另外,將檔案系統改成可讀寫後,修改的帳密才會儲存起來。最後,我就只是單純地把前輩的密碼換掉,再用他的帳號登入而已 :P 事實也證明,不要以為有帳密管理就安全,一旦主機暴露出來還是一樣很危險。目前我還沒學會的是處理 Windows 系統的部分。