pretty code

2020年11月27日 星期五

UefiMain Entry 的應用

忘記在哪裡看過,只要有 UDK Base,其實一個簡單的 Hello World 小程式也可以成為一個簡單的 Shell,我曾經試過 main Entry 的 Hello World,但只會出現 Disk Error 的錯誤訊息。

昨天看了 LAB-Z 的文章,裡面有提到一個日本人寫的書,我才恍然大悟為什麼之前無法成功,差別在我們需要使用 UefiMain Entry,而不是 StdLib 的 main Entry。

雖然曾稍微看過 Shell.c 的 code,也知道它是使用 UefiMain Entry,但我一直以為寫 Shell 有點像是寫 Windows Service 或者像在寫一支 Driver,有對應的介面需實作,這樣 OS 才能跟你寫的程式溝通,搞了半天,原來一切都是我想太多!

只要下面簡單幾行,並把編譯完的檔案改名成 BootX64.efi,放在隨身碟 EFI\Boot 下,開機時就會執行你的小程式。

#include <Library/UefiBootServicesTableLib.h>

EFI_STATUS
EFIAPI
UefiMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
    // Clear the screen
    EFI_STATUS Status;
    Status = gST->ConOut->ClearScreen(gST->ConOut);
    if (EFI_ERROR(Status)) {
        return (Status);
    }

    // turn off the watchdog timer
    gBS->SetWatchdogTimer (0, 0, 0, NULL);

    gST->ConOut->OutputString(gST->ConOut, L"Enter UefiMain \r\n");

    while (1) {

    }

    return EFI_SUCCESS;
}

2020年11月22日 星期日

PW3 自行轉檔書籍無法指定字型

版本:5.13.2

以前自行轉檔的書,如果不能更換字型,我遇到的情況都是語系誤指定為非繁體中文的語系,因此無法指定繁體中文字型。

最近第二次重練嫁衣神功後,目前已遇到 3 本書在 PW3 都無法指定字型,閱讀體驗非常的糟糕。在前一篇我已經有約略提到解決方式,目前只知道不是每本有指定 font-family 的書都不能更換字型,但不行的書一定要把所有的 font-family 都全砍光,這樣才能指定字型。

有嘗試針對某本書去微調 font-family,但都無法成功,總共嘗試過幾種 case:

01. 字型名稱不要單雙引號混用。
02. 有好幾種字型的 font-family 敘述都砍掉,只留一種字型的敘述。

看來暫時解決方式只能在嫁衣心法中新增移除指定 CSS 的功能了。


2020/11/23 更新

稍微分類一下成功與失敗的類型。另外,這篇文章是我目前看到 CSS 字型解說最詳細的。

成功

01. 有一個字型以上的混合設定,無引號+單引號組合,不只一個 font-family。
02. 有一個字型以上的混合設定,全部都是雙引號,雙引號裡面又加了單引號(" 'serif'"),只有一個 font-family。
03. 有一個字型以上的混合設定,無引號+雙引號組合、全單引號、有的使用 @font-face 語法,src 是 local 與直接指定字型,不只一個 font-family。

失敗

01. 只有一個字型設定,全部都是單引號,字型名稱只有 2 種,'sans-serif' 或 'serif',不只一個 font-family,另外有用到 font 敘述。
02. 有一個字型以上的混合設定,雙引號+單引號組合,不只一個 font-family。


2020/12/04 更新

拿 Kobo Clara HD 來當對照組,使用 kepubify 轉檔,稍微看一下 kepubify 程式碼,沒看到有對字型做什麼事。

至於轉換出來的 KEPUB 檔,在 Clara HD 上可以順利使用圓體字型,雖然我沒有再測試原始的 EPUB 檔,但我猜原始書籍的 CSS 應該是沒有什麼大問題。

結論應該就是 kindlegen 的問題居多吧?


2020/12/07 更新

最近共轉了 30 多本的書,有些我已經看過的就沒在 PW3 上檢查了,截至目前為止有出現這個問題的書本數量已經來到 8 本,錯誤率實在是有點高,趁著今天午休,馬上加上 CSS Filter 功能,希望也能一併解決轉檔的書在 PW3 閱讀時偶爾會出現的錯誤問題,每次遇到這個問題,PW3 就會自己回到首頁,需要再一次點選才能閱讀,另外,進去後雖然有記住預設字體是圓體,但顯示的完全是另外一個字體,需再任意調整成別種字體再調整回來才會正常顯示圓體。


2020/12/08 更新

昨天加上 CSS Filter 後,大概轉了 10 來本書有,其中有一本書,不是用 font-family,而是用 font 敘述,於是這本書就成了漏網之魚。雖然可以額外再做處理,但除非知道所有的字型名稱,不然無法簡單的把字型排除,算了,就當做是不足勝有餘吧。


2020/12/10 更新

拿掉 font-family 後,確定對 PW3 偶爾會發生錯誤問題沒有幫助,昨天在看同一本書時,一樣會發生此錯誤,記錄一下。

2020年11月20日 星期五

讀取書名遇到的 Bug

最近在轉檔時,遇到某本書名使用程式無法解析,程式會判斷沒有書名資訊,但用文字編輯器卻看不出有什麼問題?

該檔案是一個 UTF-8 編碼的 XML 檔,但我自己是習慣使用 Re 來解決這類小問題,我的正規表示法如下:

let regex = /dc:title.*>(.*)<\/dc:/

不論是 Javascript 或是 Python,都可以在正規表示式中任意圈出自己想要的資料,之後拿來使用就很方便。

回到問題身上,一開始會以為是不是書名裡有特殊字元導致,尤其這本書的書名接近 60 個字,實在嚇人。但把檔案和程式簡化後繼續測試,卻發生了隨機事件,有時候可以成功,有時候仍然不行?

嘗試使用 grep 和 Python 程式,兩者都可以正常執行,難道是我用的 Node.js 版本太舊導致?寫程式的大概都聽過類似的笑話:我的程式看起來沒問題呀,一定是 Compiler 的 Bug!殊不知這個是最不可能的事,如我一般的普通人寫的程式,理論上撞到這種問題的機率是非常的低,所以這個念頭也只是一閃而過。

好吧,來看看 binary 值好了,只要不是 ASCII 編碼的檔案我都很懶得看,畢竟我也無法一眼看出該中文的編碼為何?為了驗證這個問題,勢必要找出相關編碼的值才行。

檔案的 binary 內容長這樣。

書名最後 4 個字的編碼長這樣。

相比之下,結尾多了一個 E2 80 A9 的字,拿掉它之後,我的程式就恢復正常了。後來回想,之前發生隨機事件時,其實 UltraEdit 已經有徵兆,有時候針對該段文字反白複製時,偶爾便會看到一個不存在的字元,只是當時沒有想太多。

雖然問題解決了,但回到問題的本身,這個字是不合法的 UTF-8 字元嗎?

我們先來看看它的 binary 值。

1110 0010 # 1000 0000 # 1010 1001

它屬於 3 個位元的字元,其個別位元的開頭也有符合規則。將剩下的黑字再轉回 Unicode 碼,其值為 \u2029,跟用 Python Code 的 Re 結果一致。

使用 Chrome 直接開啟 XML 檔,可以正常顯示出該字元,使用全字庫網頁查詢,該字是一個中日韓相容表意文字區編碼。

查到這裡我就真的沒輒了,要再細究下去,可能要往 Node.js 用的 Re Code 方向去追查了。

後記

快下班時,無聊使用 \u2029 關鍵字查詢,才發現原來 \u2029 或是 \u2028 等字元,在正規式中是當做 a single white space,故會造成正規引擎把這一字元視為換行,而 "." 正規字元不包含換行字元,雖然可以用 "s" flag 來 match 換行字元,但書名就會包含換行字元,解決方式也很簡單,稍微更改 Re 即可。

let regex = /<dc:title.*>(.*)(\s*)<\/dc:title/


2020/11/22 更新

\u2028 是行分隔符

\u2029 則是段分隔符

不過重點還是 "." 字元不包含換行字元以外的字元, 我一直以為是包含全部字元,也算是學到一課了。

另外,這本書還真的是問題多多,放進我的 PW3 沒辦法更改字型,我目前的 PW3 版本為 5.13.2,我一向都是用 kindlegen 轉檔,這樣直式的書才能維持直式。

針對這個問題,好幾個網站都說即使是使用新型的 MOBI 格式,目前也不支持更改字型了,一定要使用 AW3 格式。但我覺得應該不是?一來我只有偶爾幾本書不行,二來我也有用 calibre 轉成 AW3 格式,結果一樣是不能更改字型。還好後來有看到一篇文章,說是把 CSS 裡面指定的字型拿掉即可,也就是 font-family 這行敘述拿掉,說也奇怪,這本書就這樣恢復正常了,我也終於可以使用我最喜歡的圓體字型來閱讀。

我後來想想,這個只是建議字型,理論上應該不影響功能才對。我目前只能想到 2 個原因,1 個是因為指定的字型有問題導致 Kindle 有 Bug,另外 1 個就是這本書不知道哪裡違反了 EPUB Spec 的規範。

我現在只能確定,隨便找了一本可以換字型的書,其 CSS 檔案也是有指定字型,差別在這本書的字型名稱沒有使用雙引號包住,而有問題的書則是同一行中有使用單引號,也有使用雙引號。理論上單雙引號皆可,只有在字型名稱包含空白時,才會使用引號包住。

2020年11月19日 星期四

Node.js 字串取代

一般來說,有原生的 Javascript 函數我都會使用原生的函數,又因為我幾乎每天都用不同程式語言在工作,導致我很難記住一些通用函數的用法。故每次都要使用關鍵字 "javascript string function" 來找可以使用的函數。

一開始我使用的是 replace,後來才發現只能取代一次,沒關係我們有另外一個 replaceAll 可以用。

不過在我的 Node.js 版本中,似乎沒有支持這個函數?還好 replace 可以使用正規表示法,記得加上 g flag 即可。

s = s.replace(/\\/g, '/');

2020年11月17日 星期二

第二次重練嫁衣神功

之前原本已經不抱希望,沒想到在忙碌的工作時光中等待測試結果的空檔,突然找到破口,就這樣又開啟了第二次重練嫁衣神功的修行。

拿出之前的檔案,稍微改一下,執行結果看起來有符合預期。

為了慶祝這個意料之外的驚奇時光,決定購買《一個都不留:克莉絲蒂120誕辰紀念版1》一書,也為這一刻做個記錄。

人生就是這樣,你永遠無法預料。

2020年11月16日 星期一

XlsxWriter 是 python 一個很常用的模組,主要是用來產生 excel 檔案,RD 最常用的場景應該是把測試結果文字檔轉成檔案,好方便後續相關工作。

之前幫別人產生測試報告時,用的都不是 python 語言,最近又幫忙產生別的測試報告,剛好對方近來比較常用 python,於是我也趁機試了一下 XlsxWriter,把一些常用語法記錄在這裡,下次再用就不用在專案資料夾裡翻找。

import xlsxwriter

def main():
    output = 'example.xlsx'

    wb = xlsxwriter.Workbook(output)
    ws = wb.add_worksheet('Sheet1')

    # freeze window
    ws.freeze_panes(1, 1)

    number_format = wb.add_format({'num_format': '00.00'})
    number_format.set_font_color('red')
    number_format.set_align('center')

    title_format = wb.add_format()
    title_format.set_align('center')
    title_format.set_bold()

    # title
    row = 0
    for col in range(8):
        title = 'Title %d' % col
        ws.write(row, col, title, title_format)

    # write something
    for row in range(1, 8):
        for col in range(8):
            s = '%02d' % (row * 10 + col)
            ws.write(row, col, s, number_format)

    wb.close()

if __name__ == '__main__':
    main()

2020年11月11日 星期三

DD0403MA_3V3

10/28 在 Amazon.com 購買了這個型號的 DC Converter 共 6 顆,11/10 就收到貨了,速度還蠻快的。

攤提運費後,一顆約要 NT $160 元,不算便宜,但買得到比較重要。

詳細規格

DD0403MA_3V3
3.5V-6V to 3.3V DC DC Step Down Converter LDO Module

Description:

Low power consumption,Low ESR Cap.Compatible DD0403MA Series LDO Module,Very suitable for lithium battery-powered
Input voltage: DC 3.5-6V
Output voltage: DC 3.3V
Long time maximum output current 300mA
Short time maximum output current 400mA
Highly Accurate:±2%
Quiescent Current : 8uA
Short Circuit Current : 30mA
Over Current Protection : 500mA
Operating Temperature: -25℃ ~ +85℃
Size(Not including pin) : 11.6 x 7.8 x 2.5mm
Weight : 0.5g
   
Attention :

This is a DC-DC voltage converter module,Must be noted when using:
1 Input voltage can not be greater than the maximum input range
2 Output power can not be greater than the maximum load for a long time
3 Input power must be greater than the output power, because the power consumption of the module itself

原本是想配合 4 顆 AAA 鹼性電池,再做一個新的 ESP8266 翻頁器,買了才想到 AAA 電池出廠電壓有可能超過 1.5V,故 4 顆串聯可能會超過電壓工作範圍,如果是 3 顆串聯又達不到我想把電池用乾的需求,因為其最低工作電壓只到 3.5V。看來還是只能配合 18650 等電池使用。

這個大小比我之前買的升壓 Converter 都還要更小,也就是說更考驗焊接技術了。

2020年11月2日 星期一

VMware vSphere 7.0 安裝時相關問題解決方式

連續好幾天都在搞這個東東,搞到都要懷疑人生了。這個問題從一開始安裝時就遇到很多坎,解決一個又有一個,一個完又一個,容我慢慢道來。

01. 無法下載 ISO 或 ZIP (客製化用)

我的工作環境總共有 2 個不同網路可以使用,不管是哪一個網路按下載檔案,網站都是無聲無息!打開 Chrome 開發者工具觀察,發現問題是出在 Javascript 的某個變數找不到,實在不太可能為了它去 debug 該網站,只好假設網站有問題,等網站管理者發現修復。從早上試到下午都沒有改善,最後是用自己的手機網路解決,我也懶得回過頭確認使用工作環境網路是否就正常了。只是據我之前下載國外軟體經驗,有時候可能是因為防火牆等關係,多試不同網路環境即可解決。

02. Realtek 8168 網卡晶片不支援

以前的版本 (6.7) 有兩種解決方式把第三方 packages 包進去:一個是使用 VMware PowerShell CLI 重 build ISO 檔,另外一個是使用高手再包裝過的 PowerShell script  (ESXi-Customizer-PS) 來解決,我這裡是使用後者。一開始會先遇到安全性問題,這個問題比較簡單,使用管理員權限執行 "Set-ExecutionPolicy RemoteSigned" 指令重新設定原則即可。

接著會遇到沒有 VMware 相關模組問題,印象中是缺少 "Core" 和 "ImageBuilder" 這 2 個模組。一開始還傻傻的去下載 "VMware-PowerCLI-12.1.0-17009493" 整包檔案,下載下來發現也不會安裝,後來發現可以直接透過官方網站安裝庫來安裝,只要使用下列指令缺什麼就裝什麼就好 "Install-Module -Name VMware.VimAutomation.Core"。

好不容易用指令產生了 ISO 檔 ".\ESXi-Customizer-PS.ps1 -izip .\VMware-ESXi-7.0.0-16324942-depot.zip -v70 -pkgDir D:ESXi-Customizer-PS-2.8.1",過程中會看到類似 API 版本不相容的 warning,沒想太多就去機器執行安裝動作,最後還是無法使用 Realtek 網卡,據這個網友的說法是 6.7 以後的 API 有更改,除非有高手提供給 7.0 使用的 packages,不然這個問題會是無解。最後跟別人借了一張 INTEL I350 網卡才讓安裝程式可以順利執行。

03. 安裝完後無法開機

跟前面幾個問題比起來,安裝過程只能說是無以倫比的順利,我都想要開香檳慶祝了。

沒想到我果然還是太嫩了,做事那有可能順風順水?一裝完就遇到無法開機的問題,開機過程 BIOS 只會無聲無息的回到 BIOS 選單,連個訊息都沒有?官網有一篇文章提到這個問題,只是提到說可能是安裝程式過程中,沒有把 UEFI Variable BootXXXX 寫好,進去選單把開機裝置 "VMware ESXi" 加入即可。第一次安裝後,我連這個裝置都沒看到,雖然我用 Linux 開機碟下指令除錯,可以看到硬碟第 1 個分割區是這個名稱沒錯,但是在 BIOS 選單都無法看到,只能看到整顆硬碟名稱的開機裝置。一開始想說先用我另外一台小電腦來測試安裝步驟,這個機器更慘,安裝前置作業就會死當,故無法做參照組。

依稀覺得可能跟 Secure Boot 有關?排列組合 BIOS 選項試了安裝好幾次,每一次都無法開機,但在某些組合下可以看到 "VMware ESXi" 這個開機裝置,嘗試使用 Linux 安裝碟從本機開機的選項也無法順利開機。在各個嘗試的過程中還發現,只要把 USB 安裝碟裡面的 "boot.cfg" 裡面的 "kernelopt=cdromBoot runweasel" 參數改成 "kernelopt=" 就可以變成混合 USB 和硬碟開機,也可以讀取 datastore 裡面的 VM 檔案,只是這種開機方式,每次都要重新設定 VM,實在不是個好選項。

認命的把官方文件大概瀏覽了一遍,也是沒有頭緒,只能確定硬碟裡面的分割區是如文件所述的 7.0 的新配置方式。

再來是猜測會不會是 BIOS 有問題?不過我用我自己 build 的 UEFI Shell 倒是可以開機,主機板官網的最新 BIOS 也只到 2014 年,暫時先不懷疑它好了。

乾脆來嘗試安裝到隨身碟好了?只不過安裝完後該 USB 裝置還是無法開機!

最後還是來看一下主機版 BIOS 版本好了,版本是這塊板子的第一個出廠 BIOS,跟最新的版本相比,時間約莫差了一年多,但是中間卻有 15 個版本的 BIOS 更新,雖然 Release Note 看不到跟 UEFI 相關的更新,還是死馬當活馬醫的更新一下 BIOS。

想不到一更新完 BIOS 後,連重新安裝都不用,就可以直接用原本硬碟裡面裝好的 vSphere 開機,終於結束了這無止境的困境。

最後開啟 vSphere 的 SSH 功能,好方便遠端登入下指令,vSphere 是一個類 Linux 的 OS,故常用的指令可能沒有,或是指令的參數不一樣,下面幾張圖分別是用了 "-df -h","/usr/lib/vmware/misc/bin/fdisk -l","/usr/lib/vmware/uefi/bin/bootorder -l" 等指令的結果。




最後一個結果比較奇怪,貌似我不是使用 UEFI mode 開機?但我記得我的開機選項是 "VMware ESXi" 無誤!

2020/11/04 更新


使用自己的小工具檢查 UEFI BootOrder and BootXXXX Variable!這一次換成需要將 BIOS 選項改成 Other UEFI OS 才能進入我的 UEFI Shell,執行結果如下圖。

2020/11/12 更新

之前詢問同事是否可以轉移網卡給我,如果以後同事專案用不到就直接做資產轉移,也可以幫公司省錢,可惜該張網卡以後專案還是會用到。跟老闆討論後,老闆也很爽快的批准採購。

我選定的是 Intel 9301CT 桌上型網卡(EXPI9301CTBLKIntel 82574L),PChome 售價 NT $1,290,應該是支持 vSphere 7.0 裡最便宜的網卡吧?我是以晶片 Intel 82574L 關鍵字來確定該張網卡有在 vSphere 7.0 的支援清單中。不過抖抖的是,國外網路上有人說他不能用?幸好到貨時一切正常(網路上似乎還有更便宜同晶片的網卡,大概是六七百塊左右,應該是非原廠卡)。

記得要登入 vSphere console,重新指定網卡才行,系統在移除舊網卡,裝上新網卡後不會自動選取網卡,一開始沒想到要做這事,只是檢查 IPv4 設定,然後就一直看到 DHCP 失敗,害我內心也抖了一下!自己的東西不能用比較沒差,公司的資產不行又要重新採購,實在是浪費錢。

另外,不知是我太 low 還是怎樣?第一次看到網卡擋板後面會提示燈號顏色的代表意義,果然是貴上 4 ~ 5 倍網卡該有的樣子。不過,我後來想想,應該是我之前買的網卡太便宜的緣故吧?