pretty code

2022年2月28日 星期一

反樸歸真的 fread and fwrite

最近有位同事要離職,為了讓同事好好交接,決定把他未完成的工作接下來做。

雖然平常開會都會討論個人進度,但因為自己不是負責的人,故也不知道原本是如何實作的?

現在變成自己要做,還是先來研究一下,有沒有什麼簡單又可以加速開發的方式?

看了一下他之前的 Code,原來 UEFI Shell 中間過程的傳遞也是一個 C struct 的變數,只是再設計成另外一種格式轉成文字檔,然後由 Windows 的另一個 Tool 來接手 parsing。

看到這裡我就覺得有點阿雜,感覺一直在訂 Spec 寫 Parser,我們似乎可以省略這個過程?反正原本的格式雖然是字串,但不參照 Spec,其實人也無法一眼看出那些數值的真實意義。

接著我直覺想到的就是使用 C struct 並搭配 fread and fwrite 函數,直接把資料存成 binary 檔案,反正現在常用的程式語言,都有 Binding C language 的能力,像我喜歡的 Go 就可以使用 cgo 的方式來使用 C Code!

剛才測試了一下,指定 struct alignment 的語法,VC and GCC 看起來都通用,最困難的點已經不是問題了,剩下的就是開發時 Debug 的問題了。


#include <stdio.h>

#pragma pack(push, 1)
struct Arg {
    int id;
    char name[3];
    int command;
};
#pragma pack(pop)

int main(void)
{
    struct Arg arg = {1, "AA", 2};

#if 1
    FILE *f = fopen("struct.bin", "ab");
    if (f) {
        fwrite(&arg, 1, sizeof(arg), f);
        fclose(f);
    }
#else
    FILE *f = fopen("struct.bin", "rb");
    if (f) {
        fread(&arg, 1, sizeof(arg), f);
        fclose(f);

        printf("%d, %s, %d \n", arg.id, arg.name, arg.command);
    }
#endif

    return 0;
}

小米盒子遙控器故障驚魂記

前天下班時不小心摔到遙控器,隔天早上使用時便沒有反應,無奈之下,上網找了好幾個 App 來使用,只有一個可以順利的使用 Wi-Fi 與小米盒子的 Android TV 配對,但它的廣告真的不是普通的多,害我都擔心起它的安全性了。

上網找了一下,有一個 open source 的軟體,網址如下:

https://github.com/NineWorlds/google-tv-remote

好不容易的解決了幾個編譯錯誤,但卻無法順利的與小米盒子連線,看起來應該是舊版協定無誤,故無法順利溝通。

還好後來無意間看到,可以安裝 Google TV 軟體,雖然它本來的目的是要取代原本的 Google 電影,但我們想要使用的只是它內建的遙控器功能。

接著我就想,既然是使用 Wi-Fi 連線,那我是不是可以來抓些封包,也許也可以自己寫一個遙控器 App 來玩?雖然我覺得它應該也是走 HTTPS 就是了!

書房的 Google Chromecast 4 被我老婆追劇罷占中,無法做測試,想了一下,還是繼續上網 Google,終於找到一篇看起來像是目前 protocol 的文章:

https://github.com/Aymkdn/assistant-freebox-cloud/wiki/Google-TV-(aka-Android-TV)-Remote-Control-(v2)

感覺就是很麻煩,故我也打消了實作的念頭,畢竟我已經有了一個沒有廣告又是官方的軟體可用,我就不折騰自己了XD

最後不死心的再敲敲我的小米遙控器,沒想到這樣就活過來了,也結束了這一場驚魂記,原來遙控器也是一種黑科技,不管摔了幾十次都還可以有驚無險呀!

2022年2月19日 星期六

Kobo Elipsa 待機三四天後沒電問題分析

這個問題大概發生了至少三次!我待機的時候都會關掉 Wi-Fi 與自動同步,故應該不是這兩個原因影響。

記得網路上有人說過第三方軟體有可能會影響待機耗電,我目前安裝的有:

NickelMenu
FBInk
KOReader
Plato
KoboPageTurner
kobofileserver

後兩個是我自己開發的軟體,平常不會自動啟動而是透過 NickelMenu 選單啟動,故應該跟這兩個軟體無關,同理還有中間那兩個 PDF 閱讀軟體,所以基本上可以排除後面四個。

至於 NickelMenu 會 Hook 到 Kobo 系統,理論上是寄生在 Kobo 系統內,故休眠時應該沒有任何動作。

而 FBInk 是去動 framebuffer 做一些顯示,故應該也與它無關才對。

我個人比較傾向是 Kobo 的 Bug,但我懶得整個 reset 測試,故也無法百分之百肯定?

最後一個方法就是寫支小程式,定時 5 分鐘記錄一下 CPU or RAM 使用排名前十名的 processes,也許就可以知道是哪些 processes 在作怪啦!

講是這樣講,但我年後上班後除了工作的程式,下班後都沒什麼心情再寫程式了,都是這個爛天氣害我不太想動XD

2022/02/20 更新

雖然還不想寫程式,但還是可以做些前置作業。在正常的 Linux 可以用 ps 來排序 processes "ps -o pid,pcpu,comm,rssize",但 Kobo 這種的 Embedded Linux 則是用 busybox 來取代 Linux 常用的指令,故並沒有 pcpu 可以用。

雖然我們可以改用 top output 來取得 CPU 使用率的排序,但據我測試的結果,感覺頻繁的使用 top 指令,也許會改變我本來想要監控的目的,目前暫時有點兩難。


2022/05/18 更新

05/13 對完信用卡帳單後就沒有關過機了,今天打開看電力還剩下 88 %,看起來似乎沒有耗電的問題了?目前版本為 4.32.19501 (2022/04/14)。

要說跟以前不一樣的地方?差別在這次開機還未使用過 Plato 等軟體,當然 NickelMenu 是一直都在的,因為它在開機時就會 hook 到 Kobo 系統!

改天嘗試使用過 Plato 後不關機再看會怎樣?

2022/06/01 更新

看起來 19501 新版本有解決耗電問題,即使有用過 Plato,在不關機的狀態下,過幾天再開的電力看起來都還算正常。

2022年2月13日 星期日

作業系統前的程式


我這邊寫的不一定是對的,可能有些前提條件,不過我可能還不是全懂?

一直以來都很想自己寫個 x86 作業系統來玩,相關的書也買了好多本,但一直沒有時間好好消化。終於在這星期開始來做些小嘗試,大部份書的第一個例子,都是藉由 BIOS 的幫助,來把磁區 0 的 512 Byte 資料載入到某塊記憶體,此資料是以 0xAA55 來結尾,故扣掉這兩個 magic number 後,我們應該還有 510 Byte 可以來寫些程式。

接著的例子就是會介紹如何切換到 big real mode 或是保護模式,好突破記憶體的限制,再來可能是想辦法把硬碟上的程式載入到記憶體,接著是初始化 C 語言環境,然後我們就可以有好用的 C 語言可用了。

雖然大部份的書入門都是這樣介紹,但我個人比較好奇的是 510 Byte 大概可以寫下怎樣的程式?如果把 x86 CPU 當成 MCU 來操作,在這樣的大小之下,可以寫一個猜數字或是簡單的打磚塊遊戲嗎?

故我第一個程式便是先嘗試用到 INT 0x10 和 INT 0x16 的 BIOS 中斷,這樣就可以印東西到螢幕,也可以讀取鍵盤的輸入字元。即使之後可能有很大機會就只是玩到這裡為止,但至少是個開始。

真正的程式很簡單不到 30 行,機器碼也只有 30 Byte,在 qemu 上跑起來也算順利。


但在真實的機器上跑便遇到兩個問題:

01. 在我家的板子上無法使用 INT 0x16 讀取鍵盤。
02. 在我自己的筆電上無法使用 USB 隨身碟開機。

我決定先把這兩個問題搞定就好。

2022/02/14 更新

我的程式沒有使用 org 告知組譯器開始位置 0x7C00,那是因為我並未宣告字串的空間,故沒有定址到那塊空間的需求,即使我有宣告字串,也可以自己計算 offset 的位置,當然使用 org 讓組譯器幫你計算是比較好的作法。順帶一提,這個 0x7C00 不是 INTEL 的標準,而是當初開發 IBM PC 5150 時用的,就一直延用至今,變成一個類似 BIOS 的標準。

2022/02/15 更新

Short jump—A near jump where the jump range is limited to –128 to +127 from the current EIP value.

opcode EB 是短跳轉,後面帶的是從目前的 EIP 要跳多少位置。這個位置是 -128 ~ +127。

故 section start 的最後一道指令 jmp check 轉成 opcode 是 EB E4(負數,二補數法),也就是往回跳 28 個 Byte,也就是 0x02 的位置,也就是 section check 的第一道指令 mov ah, 0x0d,也就是 opcode B4 0D。

mov 會隨著使用不同的暫存器而有不同的 opcode。


2022/03/08 更新

不懂 x86 也不懂 BIOS 的我,實在不知道為什麼 Legacy BIOS 的鍵盤中斷 INT 0x16 無法使用?沉思中 ...

2022/03/09 更新

找到原因了,從 Google 得知,某些 BIOS 中斷需要 stack 才能正常工作,故我們必須一併設定 SS 和 SP,但我只設定這兩個還是不正常,故把 DS、ES 也順便一起設定。

org 0x7c00
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0xb800

雖然現在鍵盤中斷可以正常工作,但我判斷是否按下 enter 鍵的 code 無法成功判斷,目前還要努力,至於其他鍵是沒有問題的。

2022/03/10 更新

即使是支小程式,在真實的機器上跑還是有很多眉角要注意,我終於知道為什麼我嘗試想要換行會無法成功,原因是我誤用了 BL 暫存器,0EH 的 INT 10h 中斷會用到 BL,但我嘗試在比較時對這個暫存器設值,導致 INT 10h 異常,同樣的之前我以為要設定 stack 才能正常使用鍵盤中斷也是錯的,只要我不要用到 BL 暫存器,即使不設定 stack,鍵盤中斷仍然是可以使用的。

寫組語用暫存器真的是要小心呀XD

最後版的程式

;org 0x7c00
;mov ax, cs
;mov ds, ax
;mov es, ax
;mov ss, ax
;mov sp, 0xb800

init:
    jmp start

check:
    mov cl, 0x0d
    cmp al, cl
    je nextline
    
print:
    mov ah, 0x0e  ;tty mode
    int 0x10

    jmp start

nextline:
    mov ah, 0x0e  ;tty mode
    
    mov al, 0x0d
    int 0x10
    
    mov al, 0x0a
    int 0x10
    
    jmp start

nextline1:
    mov ah, 0x03
    int 0x10
    
    inc dh
    mov dl, 0x00
    
    mov ah, 0x02
    int 0x10

start:
    mov ah, 0x10
    int 0x16
    jmp check

debug:
    ;mov al, 0x4c
    out 0x80, al
    hlt
    jmp debug

; padding and magic number
times 510 - ($-$$) db 0
dw 0xaa55

2022年2月11日 星期五

Kindle 閱讀器收藏夾不見的解決方式

先說解決方式!

01. filter 往下滑,選到 collection,此時會進入 collection 篩選模式。
02. 在此模式下應該會看到各個 collection 了,前面沒有星號的表示在本機看不到,點擊右邊 3 個圓點進入設定頁面,選擇「加到下載」。
03. 之後在排序那,應該就可以選 collection 了。

-------------------

昨天在討論區又看到有人的收藏夾不見了而且無法同步下載到閱讀器,除此之外,也無法在排序中點擊「收藏夾選項」,該選項為反白無法點選。該位苦主雖然有找到一篇解決方式的文章,但照他敘述似乎沒用?也許是這樣的緣故,故我點擊該篇文章後也沒有很認真瀏覽。

這兩天為了閱讀《雪中悍刀行》這本小說,在美亞買了該本書,於是又拿起我塵封已久的 Kindle Oasis 2 來閱讀。

看著看著才無意發現,原來我也沒有收藏夾了?記得前一陣子也有另一位網友有類似的問題?但因為我這台閱讀器買了沒什麼看,故我也不確定跟版本有無關係?但據我認真回想,似乎舊版本就是這個樣子沒錯?

一開始以為是不是什麼設定沒設好,翻來翻去也看出不出所以然,突然在那位苦主的留言處看到有人說 filter 選項因為太多,故看不到收藏夾的項目,雖然下拉後可以點到收藏夾的篩選選項,但這跟原本的收藏夾顯示方式似乎不太一樣?

於是又在那邊搞了老半天,最後才在收藏夾的篩選畫面中的各別收藏夾設定中找到「加到下載」的功能,選了這個之後,該收藏夾就會多個星號,之後取消篩選後,便可以在排序中點選「收藏夾選項」了!

總覺得這是個 Bug!照理說不加到下載,也應該在 ALL 的類別中看到,或者說這個本來就應該同步,不應該分兩次設定搞定?至於這個到底是 feature 或是 Bug,我也不好說XD

這次事件讓我學到三件事:

01. 不要相信別人的話XD,還是需要認真看過解決文章再下評斷,當初以為真的沒用,故忽略了該篇文章的內容。

02. 讀書最高境界就是以為沒吸收到但確實往心裡去了XD,找到解決方式後我還以為是我試出來的,後來回頭看該篇文章才發現跟他的解決方式一模一樣。

03. 寫文章的技巧或者說排版很重要,不確定是該篇文章圖片太多(應該說廣告太多)還是沒有分段,乍看真的是很不好懂,不如我列出 3 點的解決方式一目瞭然。

2022年2月6日 星期日

四維禮義廉

雖然不想在讀墨買書了,但為了做些測試及比較的購買我倒是不會排斥!剛在讀墨首頁看到18禁的書籍推薦,搞得我想測試的心情都沒了!

我雖然不是什麼道德狀元郎,也會看些謎片XD,即使讀書並不是多高尚的事,但我覺得賺錢還是要有底限,真不知道廠商在想些什麼?

雖然樂天的網站一直被人垢病,但我現在越看越喜歡樂天書城的網站了,真的是沒比較沒傷害。

最近也越來越討厭 Google,斗大的廣告佔據瀏覽器視窗下面 1/8 的位置,我之前還一直以為是我電腦中毒了,直到問了黑暗執行緒本人,才知道這是 Google 廣告改版的緣故,在網路上也找不到相關討論,網路世界的自由真的是蕩然無存了,天涯何處是吾家呀…

第一次使用家用試劑檢測 COVID-19

明天就是上班日了,我們公司需要在前一天上傳檢測結果,第一次使用的感覺是很囉嗦,步驟有點多,重點還要等 15 分鐘,確實是有點麻煩。

我老婆之前上課時也需要每幾天快篩一次,她們是使用羅氏,照她的說法是比我們的簡單一點。

這個春節的後兩天,每天都有第一次任務可以解鎖XD


2022年2月5日 星期六

世界上最遙遠的距離就是明明快到家了,但卻被迫上國道繞一個交流道再開回家

今天不知為什麼到處都是慢車?雖然我本身也不會開很快,但我都會儘量維持在速限的上限,不要造成其他用路人的困擾。

早上為了避開環快中線的幾台慢車,想說快到安坑交流道入口前還有機會切出來到環快的最外側車道,沒想到不知啥時更改了標線?改成一路上都是雙白線,說真的當時腦袋真的會突然一片空白,還好在地郎不是假的,身體自動反應切到北上車道,於是人生第一次在往新店環快上了國道繞了一圈回家XD

回到家不死心的查了一下地圖,我果然沒記錯,以前是可以有機會切出來的,也算是一個難得的經驗?