2016年5月30日 星期一

編譯 Ubuntu 的 Linux kernel 來使用 USB to RS-232 輸出訊息

如果曾經有參加過台北的 Ubuntu Hardware Summit,應該都會拿到一本橘色小手冊 Ubuntu Debugging,當中有提到可以設定幾個 Linux kernel 編譯選項中

CONFIG_USB_SERIAL_CONSOLE=y
CONFIG_USB_SERIAL=y
CONFIG_USB_SERIAL_PL2303=y

然後就可以在 Linux kernel 開機參數加上

console=tty console=ttyUSB0,115200n8

這樣就可以透過 USB to RS-232 傳輸線將 Linux kernel 訊息輸出到另外一台電腦上面,為什麼要這樣做有時候是因為 Linux kernel 開機時是什麼畫面也沒有,也不曉得中間到底發生了什麼事情,又或者是 Linux kernel 訊息出現的太快了,來不及看清楚完整的訊息一下子就過去了,也沒有來得及儲存到檔案系統上面就當機了,有著許許多多不同的情況可能會需要。

但是實際上要怎麼做才能夠編譯出 Ubuntu 上面所使用的 Linux kernel 呢?

首先是將 Ubuntu 所使用的 Linux kernel 的原始碼下載回來。

$ git clone git://kernel.ubuntu.com/ubuntu/ubuntu-xenial.git

然後我自己 commit 了一些修改 (主要是針對 amd64)。

$ git diff HEAD^..HEAD
diff --git a/debian.master/abi/4.4.0-22.39/amd64/generic.modules b/debian.master/abi/4.4.0-22.39/amd64/generic.modules
index e1b9392..53d7914 100644
--- a/debian.master/abi/4.4.0-22.39/amd64/generic.modules
+++ b/debian.master/abi/4.4.0-22.39/amd64/generic.modules
@@ -2873,7 +2873,6 @@ pixcir_i2c_ts
 pkcs7_test_key
 pktcdvd
 pktgen
-pl2303
 platform_lcd
 plat_nand
 plat-ram
@@ -4236,7 +4235,6 @@ usblp
 usbmon
 usbmouse
 usbnet
-usbserial
 usb-serial-simple
 usbsevseg
 usb-storage
diff --git a/debian.master/config/annotations b/debian.master/config/annotations
index 825012f..167ab6e 100644
--- a/debian.master/config/annotations
+++ b/debian.master/config/annotations
@@ -6609,7 +6609,7 @@ CONFIG_USB_STORAGE_ENE_UB6250                   policy<{'amd64': 'm', 'arm64': '
 CONFIG_USB_UAS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 
 # Menu: Device Drivers >> USB support >> Support for Host-side USB >> USB Serial Converter support
-CONFIG_USB_SERIAL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
+CONFIG_USB_SERIAL                               policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 CONFIG_USB_SERIAL_GENERIC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'powerpc': 'y', 'ppc64el': 'y'}>
 CONFIG_USB_SERIAL_SIMPLE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 CONFIG_USB_SERIAL_AIRCABLE                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
@@ -6641,7 +6641,7 @@ CONFIG_USB_SERIAL_MOS7715_PARPORT               policy<{'amd64': 'y', 'arm64': '
 CONFIG_USB_SERIAL_MOS7840                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 CONFIG_USB_SERIAL_MXUPORT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 CONFIG_USB_SERIAL_NAVMAN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
-CONFIG_USB_SERIAL_PL2303                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
+CONFIG_USB_SERIAL_PL2303                        policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 CONFIG_USB_SERIAL_OTI6858                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 CONFIG_USB_SERIAL_QCAUX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
 CONFIG_USB_SERIAL_QUALCOMM                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'powerpc': 'm', 'ppc64el': 'm'}>
diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu
index 505a3c7..7cb1284 100644
--- a/debian.master/config/config.common.ubuntu
+++ b/debian.master/config/config.common.ubuntu
@@ -8391,7 +8391,8 @@ CONFIG_USB_RIO500=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
 CONFIG_USB_S2255=m
-CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
 CONFIG_USB_SERIAL_AIRCABLE=m
 CONFIG_USB_SERIAL_ARK3116=m
 CONFIG_USB_SERIAL_BELKIN=m
@@ -8439,7 +8440,7 @@ CONFIG_USB_SERIAL_OMNINET=m
 CONFIG_USB_SERIAL_OPTICON=m
 CONFIG_USB_SERIAL_OPTION=m
 CONFIG_USB_SERIAL_OTI6858=m
-CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_PL2303=y
 CONFIG_USB_SERIAL_QCAUX=m
 CONFIG_USB_SERIAL_QT2=m
 CONFIG_USB_SERIAL_QUALCOMM=m

接著開始編譯 Linux kernel (在有八個 CPU cores 的電腦上)

$ CONCURRENCY_LEVEL=8 fakeroot debian/rules clean binary-generic

最後就會在上層目錄產生 Ubuntu 所使用的 Linux kernel 的 Debian packages 了。

$ ls -1 ../*.deb
../linux-cloud-tools-4.4.0-22-generic_4.4.0-22.40_amd64.deb
../linux-headers-4.4.0-22-generic_4.4.0-22.40_amd64.deb
../linux-image-4.4.0-22-generic_4.4.0-22.40_amd64.deb
../linux-image-extra-4.4.0-22-generic_4.4.0-22.40_amd64.deb
../linux-tools-4.4.0-22-generic_4.4.0-22.40_amd64.deb

這樣就可以將這些 Debian packages 拿去安裝使用了。

最後我放了一份在 http://people.ubuntu.com/~fourdollars/usb2rs232/ 上面,也許有人剛好也需要想要測試一下效果如何。

參考資料:https://wiki.ubuntu.com/Kernel/KernelDebuggingTricks

2016年5月29日 星期日

在 Ubuntu 16.04 上面使用自然人憑證報稅

發現完全可以依照兩年前寫過的在 Ubuntu 14.04 上面使用自然人憑證報稅的步驟,現在不管是 i386 的或是 amd64 的都可以運作。

只是我不明白為什麼自然人憑證用戶端元件安裝 (HiPKIClient) 上面完全沒有提到有 amd64 的版本可以使用。

這樣一來我就不用設法去生一個 i386 的環境來使用。

另外今年大家都會遇到的問題是 HiPKIClient 沒有合法簽章,因為現在的 Firefox 預設上都強制要求 extension/plugin 要有合法簽章才能夠使用,不然的話就要手動停用強制簽署的功能。

「你可以在 Firefox 設定編輯器(about:config 頁面)將 xpinstall.signatures.required 修改成 false 來暫時停用強制簽署的功能。」

還有要注意安裝 EZ-100PU 讀卡機的驅動程式有沒有符合系統的版本,通常使用指令

uname -i
就可以知道當下的系統是 i386 還是 x86_64 (aka amd64) 了。

$ unzip -l 201511920271676073.zip 
Archive:  201511920271676073.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2011-08-10 15:04   EZUSB_Linux/
    69340  2011-08-10 14:54   EZUSB_Linux/EZUSB_Linux_x86_64_v1.5.3.zip (amd64)
    58687  2011-08-10 14:54   EZUSB_Linux/EZUSB_Linux_x86_v1.5.3.zip    (i386)
       58  2008-04-09 13:12   Archive created by free jZip.url
---------                     -------
   128085                     4 files

最後就是要安裝 Java 7 才能夠正常使用,但是 Oracle 已經不再維護 Java 7 了,Oracle 目前建議使用的是 Java 8,但是 Java 8 完全無法在 Ubuntu 16.04 (amd64) 上面的 Firefox 46.0.1 正常使用,不曉得國稅局何時才會請中華電信還是關貿網路來解決這個問題。

出社會工作後都是用 Linux 系統在報稅,可是十幾年過去了,還是覺得政府做得很糟糕。:-(

2016年5月8日 星期日

在 Ubuntu 16.04 上面製作 FreeDOS 開機的 USB 隨身碟

首先是安裝 makebootfat 這個套件。

$ sudo apt install makebootfat

然後就可以參考 /usr/share/doc/makebootfat/README.Debian 這份文件來製作 FreeDOS 開機的 USB 隨身碟,只不過文件內容有點錯誤,所以我根據我的喜好調整了一下,以下假設 USB 隨身碟的 device node 在 /dev/sdb。

$ mkdir ~/tmp/fs-root
$ cd ~/tmp

$ wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/kernels.zip
$ unzip kernels.zip source/ukernel/boot/fat*.bin
$ cp -v source/ukernel/boot/fat*.bin .

$ wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/commandx.zip
$ wget http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/unstablx.zip
$ unzip commandx.zip bin/command.com
$ unzip unstablx.zip bin/kernel.sys
$ cp -v bin/kernel.sys bin/command.com fs-root/

$ sudo makebootfat -o /dev/sdb -L FreeDOS -E 255 -1 fat12.bin -2 fat16.bin -3 fat32lba.bin -m /usr/lib/syslinux/mbr/mbr.bin fs-root/

這樣就可以產生 FreeDOS 開機的 USB 隨身碟,不過真正在使用時似乎還是會遇到一些相容性的問題,像是我在 Dell 電腦的 Legacy BIOS mode 都可以正常使用,但是在我自己的 Lenovo ThinkPad X200 上面就不能用。

2017/02/14 補充:做了一個快速使用的腳本程式 mkfreedos.sh

2016年5月6日 星期五

在搭配 32-bit UEFI BIOS 的電腦上面安裝 Ubuntu 16.04 amd64

最近剛好拿到一台硬體上面的 BIOS 只有支援 32-bit UEFI,但是 Ubuntu 16.04 以前的版本包含 Ubuntu 16.04 本身的標準安裝媒體都沒有支援。

不過還好找到 http://askubuntu.com/questions/392719/32-bit-uefi-boot-support 提到了可以借用 Debian multi-arch 的 netboot ISO 裡面的 GRUB 檔案來繞過啟動的問題。

首先是要將 UEFI BIOS 當中的 Secure Boot 關掉,然後將 http://releases.ubuntu.com/16.04/ 上面的 ubuntu-16.04-desktop-amd64.iso 下載回來解開到 USB 隨身碟上面。

$ sudo apt install p7zip-full
$ cd /media/user/USBStick
$ 7z x ~/ubuntu-16.04-desktop-amd64.iso

然後是到 http://cdimage.debian.org/debian-cd/current/multi-arch/iso-cd/ 上面將 debian-8.4.0-amd64-i386-netinst.iso 下載回來,然後掛載起來將當中的 GRUB 檔案複製到 USB 隨身碟上面。

$ sudo mount ~/debian-8.4.0-amd64-i386-netinst.iso /mnt
$ cp -rv /mnt/boot/grub/i386-efi /media/user/USBStick/boot/grub/
$ cp -v /mnt/efi/boot/bootia32.efi /media/user/USBStick/EFI/BOOT/

最後將 /mnt 跟 USB 隨身碟都卸載就可以拿去安裝 Ubuntu 16.04 amd64 了。

$ cd
$ sudo umount /mnt
$ umount /media/user/USBStick

安裝過程中我有接著有線網路,並且提供 DHCP 給它取得 IP,所以它會自己連上網路去下載 grub-efi-ia32 及 grub-efi-ia32-bin 回來安裝使用,這是 Ubuntu 16.04 amd64 之所以能夠正常安裝使用的重要步驟。

另外一個重點是 Debian multi-arch 的 netboot ISO 裡面的 GRUB 檔案可能沒有支援 Secure Boot,還有 Ubuntu 16.04 也沒有提供 grub-efi-ia32-signed 這樣的套件,所以遇上了無法關閉 Secure Boot 的 UEFI BIOS 就無法使用這個方法來安裝了。

補充:只要再使用「自製 Ubuntu 13.04/12.10/12.04.2 與 Debian 7.0 測試硬體安裝使用的 USB 隨身碟」裡面提到的指令,就可以製作出同時可以使用於 Legacy BIOS、32-bit UEFI BIOS 與 64-bit UEFI BIOS 的 Ubuntu 16.04 amd64 安裝 USB 隨身碟

$ sudo apt install grub-pc-bin
$ sudo grub-install --removable --target=i386-pc --root-directory=/media/user/USBStick/ /dev/sdb

不過後來又發現,其實只要使用 Ubuntu 16.04 裡面的工具就不需要使用 Debian multi-arch 的 netboot ISO 裡面的 GRUB 檔案了。 Orz...

$ sudo apt install grub-efi-ia32-bin
$ sudo grub-install --removable --target=i386-efi --root-directory=/media/user/USBStick/ /dev/sdb

當然 grub-pc-bin 跟 grub-efi-ia32-bin 都是從 Debian 而來的,只是使用上最好都維持同樣的版本,比較不會遇到奇怪的問題。