2011年8月24日 星期三

Windows CE 的 kernelIoControl


這些是 KernelIoControl 中 FILE_DEVICE_HAL 用的 control code, 號碼是十進位, 這些是從 FreeScale 的 BSP 裡挖出來的, 還不是全部的 Control Code..

CTL_CODE(FILE_DEVICE_HAL, xx, METHOD_BUFFERED, FILE_ANY_ACCESS)

xx:
01 HAL_GET_DEVICE_INFO
03 HAL_GET_IP_ADDR
04 HAL_RADIO_CNTRL
05 HAL_DDK_CALL
06 EDBG_REGISTER_CLIENT
07 EDBG_DEREGISTER_CLIENT
08 EDBG_REGISTER_DFLT_CLIENT
09 EDBG_SEND
10 EDBG_RECV
11 EDBG_SET_DEBUG
78 KITL_STARTUP
79 KITL_INTRINIT
80 KITL_IS_KDBG_REGISTERED

// KITL PowerOn/Off ioctl, *lpInBuf = 0 for off, 1 for on.
81 KITL_POWER_CALL
12 SET_KERNEL_COMM_DEV
13 HAL_GET_UUID
14 HAL_INIT_RTC
15 HAL_REBOOT
16 HAL_HALT
17 SET_KERNEL_DEV_PORT
18 HAL_TRANSLATE_IRQ
19 HAL_GET_RIO_INFO
20 HAL_ILTIMING
21 HAL_GET_DEVICEID
22 HAL_PROFILE
23 HAL_SET_DEVICE_INFO
24 QUERY_PHYSICALMEM
25 PROCESSOR_INFORMATION
35 HAL_GETREGSECUREKEYS
36 HAL_REQUEST_IRQ
38 HAL_REQUEST_SYSINTR
54 HAL_RELEASE_SYSINTR
// IOCTL to get KITL transport info
37 KITL_GET_INFO
40 HAL_ENABLE_WAKE
41 HAL_DISABLE_WAKE
42 HAL_GET_WAKE_SOURCE
61 HAL_PRESUSPEND
// IOCTL to tell OEM to initialize registry on boot
44 HAL_INITREGISTRY

// IOCTL to give OEM a more full-featured init when the kernel is ready to go
// and before any apps are started
45 HAL_POSTINIT

// IOCTL to ask OEM whether to force clean registry hive
49 HAL_GET_HIVE_CLEAN_FLAG

// IOCTL to ask OEM the reason for power on
50 HAL_GET_POWERONREASON

// IOCTL to get random hardware seed
52 HAL_GET_RANDOM_SEED

// IOCTL to ask OEM for a RAM region to put the registry hive into
53 GET_HIVE_RAM_REGION

// IOCTL to tell OEM to save the RAM region where the registry hive is stored
55 SAVE_HIVE_RAM_REGION

// IOCTL to write XIP section.
46 HAL_WRITE_XIP
47 HAL_XIPCHAIN

// IOCTL for authenticate device
60 HAL_AUTHENTICATE_DEVICE

// IOCTL for WHQL testing (used to check whether hardware is in a jumpered test mode)
56 WHQL_TEST_MODE

// IOCTL for retrieving location and size of bootloader in flash
57 HAL_GET_BOOTLOADER_PARAMS

// IOCTL for retrieving the signed state of an OS image
58 HAL_GET_IMAGE_SIGNED_STATE

// IOCTL to query for a default display resolution.
63 HAL_QUERY_DISPLAYSETTINGS

// IOCTL to query device for device-specific information
64 HAL_QUERY_DEVICE_SETTINGS

// IOCTL to allow the HAL to override the extension region
65 HAL_GET_BIN_CHAIN

// IOCTL to retrieve cache information
66 HAL_GET_CACHE_INFO

// IOCTL to control OEM-specified profiler
67 HAL_OEM_PROFILER

// IOCTL to allow the networking component interrupts to use one SYSINTR_NETWORK_SHARED
68 HAL_SYSINTR_NETWORK_SHARED

// IOCTL to allow OEM specify MAC address for RNDIS
69 HAL_GET_RNDIS_MACADDR

// IOCTL to allow OEM's to specify if a partition is to be formated before being mounted.
70 HAL_QUERY_FORMAT_PARTITION

// IOCTL used by halflat display driver
71 HAL_DDI

// This IOCTL enables/disables update mode. It's used when updating system images and it sets/clears a flag in
// an OEM-defined location that's interpreted by the initial program loader (IPL) at boot time. Based on the
// flag, the IPL will either boot the OS image or it'll load the update loader which starts the update process.
//
// The IOCTL takes a single boolean input parameter: TRUE == update mode and FALSE == normal OS
//
77 HAL_UPDATE_MODE

// IOCTL used by kernel to query page pool parameters from the OAL
// The IOCTL takes no input parameters but returns an NKPoolParameters struct as output.
82 HAL_GET_POOL_PARAMETERS

////////////////////////////////////////////////////////////////////////////////
// VBridge support in kernel, used by VMini (Null miniport driver).
//
26 VBRIDGE_GET_TX_PACKET
27 VBRIDGE_GET_TX_PACKET_COMPLETE
28 VBRIDGE_GET_RX_PACKET
29 VBRIDGE_GET_RX_PACKET_COMPLETE
30 VBRIDGE_GET_ETHERNET_MAC
31 VBRIDGE_ADD_MAC
32 VBRIDGE_SHARED_ETHERNET
33 VBRIDGE_CURRENT_PACKET_FILTER
34 VBRIDGE_802_3_MULTICAST_LIST
39 VBRIDGE_WILD_CARD

//
// These are only handled in vbridge.lib
//

42 VBRIDGE_WILD_CARD_RESET_BUFFER
43 VBRIDGE_WILD_CARD_VB_INITIALIZED
// Ioctl to retrieve OutputDebugString
48 EDBG_GET_OUTPUT_DEBUG_FN
51 EDBG_IS_STARTED
// IOCTL to retrieve hardware-generated entropy
62 HAL_GET_HWENTROPY

例如呼叫已經被串接好的 RTC_init 就像這樣:
SYSTEMTIME tTIME = { 0 };
KernelIoControl(CTL_CODE(FILE_DEVICE_HAL, 14, METHOD_BUFFERED, FILE_ANY_ACCESS), &tTIME, sizeof(SYSTEMTIME), NULL, 0, NULL);

至於串接到 OEM function 這個是在 WinCE 裡被定義好的, 能不能改我就不確定了..
{WINCE_ROOT}\\PLATFORM\\COMMON\\SRC\\INC\\oal_ioctl_tab.h :

{ IOCTL_HAL_INIT_RTC, 0, OALIoCtlHalInitRTC },

2011年8月12日 星期五

嗯, 真的, why so serious?

我現在不會想那麼好心跟客戶打招呼, 我只是想告訴客戶, 前面有水雷, 不要過去.

2011年8月5日 星期五

Windows CE 輸入法...

先寫在這做筆記, 我不確定完全正確...
在做 windows CE 的東西時, 只要碰上非英語語系界面時都會碰上這個問題:

ERROR: C:\WINCE600\public\common\oak\drivers\keybd\LAYMGR\.\LayMgr.cpp line 1600: MapVirtualKey: No input language installed
ERROR: C:\WINCE600\public\common\oak\drivers\keybd\LAYMGR\.\LayMgr.cpp line 1411: KeybdDriverVKeyToUnicode: No input language installed

google 半天的結果當然是無解.. (google 能找到答案的問題本來就不叫問題..), 如 debug console 所說, 這是欠輸入法, 但只講對 1/5, 實際上這除了欠輸入法以外, 還欠 keyboard layout. 而更奇怪的是, CE 上 keyboard layout 竟然是用輸入法所用的代號..

以下假設是日文環境, 輸入法用 IME 3.1, BSP會這樣設定:
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
@="00000411"
[HKEY_CURRENT_USER\Keyboard Layout\Preload\1]
@="00000411"

這個在 \wince600\PUBLIC\COMMON\OAK\DRIVERS\KEYBD\LAYMGR.reg 裡, 而被 BSP 用的 platform.reg include 進來:

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\00000411]
"Layout File"="kbdmouse.dll"
"Layout Text"="Japanese"
"PS2_AT"="kbdmouse.dll"

但實際上這樣做有幾個問題在於
1.實際上沒有一個輸入法叫 00000411, 這是國家代碼, 當然不會是輸入法代碼..
2.IME 3.1 的輸入法代號叫 e001, 所以在 laymgr.cpp 中尋找的是 e0010411....
3.這個 e0010411 會在以上的 Preload 裡尋找, 如果沒有的話, 表示預設就沒有它..
4.這個 e0010411 也會 在 Layouts 裡尋找, 如果沒有, 就沒有對應表..

這個問題源自於 laymgr.cpp GetDefaultInputMethodName()中的一行
_tcsicmp( szTempInputMethodName, szTempDefaultInputMethodName)
(line 2963 at wince 6.0 R3 patch 2011-06-30) 中的判斷, 傳進去的是輸入法代碼 + 國碼一起比較, 也就所以為什麼英語語系 (00000409) 都沒有問題, 因為英語語系沒有輸入法, 前面都是0, 所以不會有找不到的問題.
(實際上我會建議在 laymgr.cpp 中安插自己的 debug message 把輸入法的代號 dump 出來, 以利日後 registery 值的建立.)

也就是說, 如果是用日文語系+IME的話, laymgr 會去找一個叫 "日文語系+IME" 的鍵盤, 實際上當然是不會有這種東西, 但我們要在 registery 裡造個假的去騙過檢查...

所以我現在用的設定是這樣子, 平臺是 FreeScale i.MX35

i.MX35 用的 platform registery key 在:
C:\WINCE600\PLATFORM\iMX35-3DS-PDK1_7\FILES\platform.reg
修改幾個:
; #include "$(DRIVERS_DIR)\keybd\LayMgr.reg" ;<= mark 掉
因為全域變數不一定 100% work, 所以被 include 進去的東西
往往會被設定成預設的 0409 而非想要的其它語系.

在最後面加上:
[HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\KEYBD]
"DriverName"="kbdmouse.dll" ;這是預設 driver.
[HKEY_CURRENT_USER\Keyboard Layout\Preload]
@="e0010411" ;預設使用的輸入法
[HKEY_CURRENT_USER\Keyboard Layout\Preload\1]
@="00000409" ;有這三個可以備選
[HKEY_CURRENT_USER\Keyboard Layout\Preload\2]
@="e0010411"
[HKEY_CURRENT_USER\Keyboard Layout\Preload\3]
@="00000411" ;這個是被列給 keyboard layout 用的.
[HKEY_LOCAL_MACHINE\Security\Policies]
@="00000411" ;這個不確定幹麻的.
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\00000409]
"Layout File"="kbdmouse.dll" ;其實這裡指的都是對應表.
"Layout Text"="US"
"PS2_AT"="kbdmouse.dll"
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\e0010411]
"Layout File"="KbdNopJpn1.dll" ;JPN IBM layout 是 jpn1, NEC 是 jpn2.
"Layout Text"="Japanese"
"PS2_AT"="KbdNopJpn1.dll"
[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Layouts\00000411]
"Layout File"="KbdNopJpn1.dll" ;這裡也要再設定一個.
"Layout Text"="Japanese"

其中指定用 kbdnopjpn1.dll 的主要原因, 是因為它有 export PS2AT_00000411 跟 IL_00000411 兩個 function 出來, 這個是 CE 一拿到就會有已經建好的東西, 其它像法文鍵盤等, 就要參考網路上的文章 (也是被找到最多的文章..)

開機進 CE 裡後, 還要先把輸入法切回英數再切回 IME 才可以兩個都載入進來.

ps. OS component 中, international->locale_specific_support->Japanese->Keyboard 確定要選. 而 NOP-en., NOP keyboard/mouse japan2 這兩個其實一定要選, 才會有 kbdnopjpn1.dll 被包進 kernel image 中, 圖中是因為 BSP 還啥的影響不能全選:


不過仍有繞路走的解法. 在 sysgen 時, 會幾乎把所有不管你有用到沒用到的 .DLL 全部編譯, 先盡可能浪費你所有的時間後, 然後再看要不要加進來... 也就是說, 編好後, 用搜尋是可以搜尋的到這些 .DLL 檔案的. 把這些 .DLL 檔案抓出來後, 可以用內建檔案的玩法給它內建在 kernel image 裡.
也就是修改 platform.bib, 加上
KbdNopJpn1.dll $(_FLATRELEASEDIR)\KbdNopJpn1.dll NK U
這樣在執行時, 會擺在 \\windows\\ 下, 輸入法檔案是可以找的到的.

先這樣, 這還不是很好的解法...

2011年7月29日 星期五

穩定

也許只是一秒, 我想要有陸地, 有一個立足點可以站, 這樣我的雙手才可以穩定的做別的事.

也許只是一小時, 我想要安靜, 只因為我想要思考下一步該怎麼走.

也許只是一天, 我想要有個僻護所, 只因為我每天都需要睡幾小時, 否則沒有體力面對明天.

也許只是幾年, 我只想要有個穩定的工作, 因為我要有穩定的經濟來源來支配生活所需.

也許時間長, 也許時間短, 我一直覺的, 不管做什麼事, 總要有個穩固的基礎, 才能往上爬, 然而..



我今天才意識到, 這些只是一時的穩定, 它不但只是一時, 而且可能還只是一場巧合, 而且更有失去這些辛苦打起來基礎的機會. 我以前以為在這個世界上要找到能一直存活下去的方法是存在的, 長大後才慢慢明瞭到這種學能並不存在, 用上這些學能的那一天, 我開始發現然還是要一直學習一直成長, 才能在人群中走下去, 當在人群中行走數年, 我才發現能幫助你的人是一時的, 人群更不會是永遠存在的, 而我卻需要這些人群換得我日常所需...

我知道這世界上唯一不變的就是 "一直在改變", 只是真正面對時, 那又是另一種心情...

2011年6月29日 星期三

最後一天

會寫下這文章其實並不代表今天是什麼的最後一天, 也不是紀念什麼日子, 而我想講的是, 每天都是最後一天.

其實這是一年多前開始到現在都有的想法, 我每天都曾面對一種心情, 像父親每天為我準備的早餐, 但今天是最後一天為我準備早餐, 也是我最後一份父親為我準備的早餐, 我會怎樣去面對呢? 哽咽著, 放在一邊, 還是若無其事的吃掉? 沒了它之後, 哪一天哪一刻想再回到那個感覺時呢? 嗯, 沒錯, 現在就是我想要找的那一刻, 回頭看同樣的事物, 會有失而復得的感受.

這樣看起來會負面, 會灰色嗎? 嗯, 沒錯, 是非常的灰色, 我只是把事情擺在最壞的角度去想它而已, 當日常的某些事物消失了, 開始想念起它了, 總是會有那種 "當初為什麼沒有好好珍惜呢!?" 的想法, 把未來的時間點拉回到現在, 就如同把現在的時間點拉回過去一樣. 但是, 已經有的, 很多人會把它當理所當然, 不會去珍惜, 因為不曾去考慮過這些被認為理所當然存在的事物不見時的樣子.

當今天是你生命中的最後一天, 最後一刻, 也許第一個想到的是, 想要做什麼, 但實際上走到那一刻時, 想到的卻是什麼還沒做. 而我們曾擁有過完成它的時間跟機會嗎? 通常有, 而且很多很多, 多到不會去注意.

也就所以這樣, 我不會當拿別人的好處聽別人的好話是應該的, 享受自由跟衣食無虞的生活是天賦人權, 每一刻的美好, 都有機會成為最後一次, 不珍惜就沒有後悔的機會.

2011年6月23日 星期四

PDF-XChange Viewer

在這裡挖來的, 而且又免安裝, 又有中文化:
簡而言之, 現在換這個 PDF reader, 只是它預設不會把書籤 (bookmark) 功能打開, 要在 view -> bookmarks 裡另外打開它.

adobe 的東西嘛.... ignore it....

2011年6月9日 星期四

busybox 下的校時

[修正一下以前的問題..]
busybox 我不知道幾版開始有支援 ntpd (ntp server/client), 而這個 ntpd 的用法跟以前的 ntptime/ntpdate 有點差別...

ntpd 對 time server 校時 (假設 server 用 watch.stdtime.gov.tw):
#
mv /etc/localtime /etc/_localtime
ntpd -nqp watch.stdtime.gov.tw
hwclock -w
mv /etc/_localtime /etc/localtime
#

這樣就可以將 ntpd 抓回來的時間設定在 RTC 上.

但如果此時 /etc/localtime 沒有東西的話, ntpd 會抓回沒有 GTM 修正的時間, 系統時間 (date) 也不會有 GTM offset 修正. 這時還要再加上 /etc/localtime 的設定, 才會有 GTM 的 offset.
這裡是中華民國臺北 (嚴正強調絕不是中國台北), 時區是 GTM+8, 時區資料在 /usr/share/zoneinfo/Asia/Taipei, 可以直接 ln -s /usr/share/zoneinfo/Asia/Taipei /etc/localtime 或乾脆直接把檔案 co 過去變 localtime 檔案, 這樣系統時間會參考 /etc/localtime 的資料, 修正為當地時區時間.

但 1.18.4 版的 busybox 似乎有個問題, /etc/localtime 存在時, ntpd 抓回來的時間也會自動做 GTM offset 修正, 如果此時剛上述一樣, 後面再做一個 hwclock -w 的動作時, h/w RTC 被存進去的時間就不再是沒有 GTM offset 的時間, 而是被加過的時間, 然後下次開機回來看時, 會發現系統時間被設定成 GTM offset 被加過兩次的時間....

所以 ntpd 在抓時間時, 要先把 /etc/localtime 先給 hidden 起來, 讓 ntpd 抓到的都是 GTM+0 的時間. 待 ntpd 設定好時間後, 再把 /etc/localtime 修正回來, 讓系統時間回到 GTM+offset 的時間上..