2025年8月24日 星期日

Orange Pi One / Orange Pi Zero 升級記憶體

動機

在網路上有人賣淘汰的 Orange Pi One 和 Orange Pi Zero,因為便宜,又收了一堆舊的 3D 印表機來改,所以就買了不少的 Orange Pi One 和 Orange Pi Zero。其中 Orange Pi One 的記憶體都是 512MB,Orange Pi Zero 則有 256MB 和 512MB。

仔細看 DDR RAM 的編號,有 K4B2G1646E 和 K4B4G1646E,前者為 8*256M = 2G (bits),後者為 8*512M = 4G (bits)。編號的其中幾個字母,可能不同,不重要。Orange Pi One 使用 2個 K4B2G1646E,總共有 512MB。若換成 2個 K4B4G1646E,則有 1GB,請參考下面的連結分享。Orange Pi One 可以只裝一個記憶晶片,但不能裝2個不同型號的芯片。

後來查 H2+ 和 H3 的規格,可支援 2GB 的記憶空間。又找到相近型號的記憶晶片 K4B8G1646Q,假如把 Orange Pi Zero 換成這個晶片,就能有 1GB 的記憶體。先買 3個來測,換了之後,確定能用。

面臨的問題是,從來沒有焊過 BGA 封裝的晶片。因此花重金買了一些設備,然後再花了一兩個星期,用沒用到的 DDR2 記憶模組來練習 拆焊,植錫,焊接。最終成功換上記憶晶片,同時發現 BGA 晶片蠻耐操的,加熱 3,4分鐘,重複 3,4遍,甚至不小心用洗板液急速冷卻,仍然正常運作。

參考



K4B4G1646E / K4B8G1646Q 

  • Density: 4 Gb (Gigabits) / 8 Gb (Gigabits)
  • Package: 96 FBGA
  • Speed: 1600 Mbps (Megabits per second)
  • Voltage: 1.35 V (Volts)
  • Temperature: -40 to 95 °C (Celsius)
  • Organization: 256M x 16 / 512M x 16
  • Product Status: End of Life (EOL)

工具

  • 熱風槍,不可少的工具,可以在淘寶買,指定 110V
  • 助焊膏
  • PCB 固定架
  • 錫球,BGA 焊盤間距 0.8mm,挑選錫球直徑 0.45mm
  • 植錫網,植錫架
  • 洗板液
  • 鑷子

植錫

現在的記憶體晶片都是 BGA 封裝,雖然買來的記憶體晶片,都已植錫,但焊接失敗,就必須拆下,重新植錫,再次焊接。因此,在焊接前,先把 BGA 的植錫和焊接功夫練好。翻找手邊的剩餘材料,發現 DDR2 的記憶模組是使用 BGA 封裝的晶片,現在又已用不上,正好用來練習。花了一個多星期時間練習,拆裝了幾條記憶模組,十幾顆晶片,慢慢掌握其中的技巧。

可以買記憶體用的小鋼網。雖然有買簡易植錫架,但後來在網路上看到有人分享的經驗,發現這樣做更好。先徒手植 2顆上去,當作鋼網的定位點,這樣就不需使用植錫架。

徒手植錫,要練一下。練成後,不用鋼網,也可以用手排錫球,植錫。但實在很費時間,只能當練功。關鍵在於,塗上薄薄一層助焊膏,可以黏住錫球。太多助焊膏,助焊膏一化開,錫球會漂走。熱風槍的風速開到最小,先用遠一點的距離吹,讓錫球先黏在焊盤上,再靠近吹,讓它整個化開,完美地吸在焊盤上。

在焊盤上均勻塗抹助焊膏,一定要用助焊膏,錫球才能黏在焊盤上。這很關鍵,不能太少,不然錫球都會黏在鋼網上。但也不能太多,不然錫球會飄。再把鋼網套上,背後可以用鋁箔紙貼住。

用鑷子一顆一顆把錫球放上去。利用助焊膏黏性,把球黏在鑷尖,再黏到焊盤上。

錫球全部擺好後,用熱風槍,380度,慢慢吹。看影片,都是 40幾秒就好。但我就是要吹到 2分鐘以上才行,不知差在那裡。但也發現,用這溫度吹個 3分鐘多,晶片也還可以正常工作,就放心地做吧。

拆焊與焊接

植球和焊接,最好有計時器,不要光憑感覺。要有耐心,常要好幾分鐘,時間不夠,錫沒全化,硬來,只會把東西弄壞,更麻煩。

拆焊,可以用 450度。PCB上的塑膠零件,用鋁箔紙保護一下,以免吹壞。注意一下小零件,不要不小心把它吹飛或撞飛。若真不幸弄飛了,要留下來,事後再焊回去。一定要等錫全化了,再把晶片夾起來,一次就要拿起來。若不幸一次不成,部分黏住,不要硬拔,會把焊盤拔壞。

再來就是把晶片焊回去,用 380度,我要吹到 3分鐘,才能焊接成功。先對 PCB 吹個一分鐘,上助焊膏,碰到就化開,可以塗抹均勻。

買來的晶片,可能不是新品,但都有植錫。可惜,我直接焊接,都會失敗。反倒是我自己植錫的,吹個 2分鐘 ~ 3分鐘,就能自動歸位。不知是不是 有鉛 和 無鉛 的差別。後來乾脆全部重新植錫再焊,比較不會失敗。

另外,影片的經驗分享,都是用鑷子輕推一下,會重新歸位,判斷錫全化呈流動狀態,為焊接成功的判斷。但手抖得厲害,一不小心就推到位置之外,也看不出塌陷的瞬間。後來發現有個影片,晶片擺得不正,錫全化呈流動狀態時,晶片自動歸正了。

我就在放晶片時,對準位置之後,稍稍把它弄歪一點,讓晶片邊緣和定位白線不會對齊。等加熱到晶片和白線對齊,就成功了。

後來,發現可以吹到 3分鐘,晶片仍是正常的,在重新植錫後,就固定吹個 3分鐘,比較保險。

好不容易,成功了,升級為 1GB 的記憶體。






2025年8月7日 星期四

修改 Klipper LCD 螢幕的 menu

在 Klipper 的 LCD 的功能表中,增加一些功能,方便使用。

顯示 IP

在 LCD 顯示 IP,參考 goopypanther/klipper_network_status。參考它的說明,執行 install.sh。或是直接將 network_status.py 複製到 ~/klipper/klippy/extras/ 目錄下,再重新開機,就會生效。然後依照說明,在 printer.cfg 建立功能表。

[menu __main __system]
type: list
name: System

[menu __main __system __network]
type: list
name: Network

[menu __main __system __network _mdns]
type: command
name: mDNS: {printer.network_status.mdns}

[menu __main __system __network _ethip]
type: command
name: Eth IP: {printer.network_status.ethip}

[menu __main __system __network _wifissid]
type: command
name: Wifi SSID: {printer.network_status.wifissid}

[menu __main __system __network _wifiip]
type: command
name: Wifi IP: {printer.network_status.wifiip}

我是放在 [System] 的子功能表之下。


關機功能

參考 Shutdown host from menu with mainsail?

Klipper 是在 Linux 系統下執行,最好執行 shutdown 指令,關閉系統後,再關閉電源,以免資料流失。

首先,透過 kiauh 的 "4) [Advanced]",安裝 "Extras: 8) [G-Code Shell Command]"。

# shell command
[gcode_shell_command reboot_host]
command: reboot

[gcode_shell_command shutdown_host]
command: shutdown now

# 功能表
[menu __main __system __reboot_host]
type: command
name: Reboot Host
gcode:
    M117 Reboot Host
    { menu.exit() }
    RUN_SHELL_COMMAND CMD=reboot_host

[menu __main __system __shutdown_host]
type: command
name: Shutdown Host
gcode:
    M117 Shutdown Host
    { menu.exit() }
    RUN_SHELL_COMMAND CMD=shutdown_host




2025年8月4日 星期一

Orange Pi Zero 安裝使用

在網路上有人出清二手的 Orange Pi Zero,雖然是十多年前的產品,但拿來當 Klipper 的上位機還蠻適合的。

Orange Pi Zero 和 Orange Pi One 類似,但有 wifi,不用再另外花錢買 wifi 裝置。另外,只有一個 DRAM 晶片,因此記憶體最大只有 512MB,預設是 256MB。使用 H2+ CPU,是 H3 CPU 的閹割版,但對 klipper 的運作影響不大。

賣家出貨,512MB 和 256MB,隨機出貨,256MB 的板子比較多。

Pi Zero 與 Pi One 的差異

Orange Pi One 發表於 2016年 1月,CPU 為 H3,2個記憶體晶片,標準 512MB,最多可以升級至 1GB。Pi Zero 則發表於 2016年 12月,CPU 為 H2+,H2+ 為 H3 的降級版,1個記憶體晶片,標準 256MB,最多可以升級至 512MB。

Armbian/build 建立的 Pi Zero 的 image,在使用時有一些問題,如 reboot 會卡在 "Restarting system"。後來無意中,發現使用 Pi One 的 image 也可以開機,且 reboot 可正常開機。看電路圖,Pi One 和 Pi Zero 很類似,可能這樣才能用 Pi One 的 image 來啟動 Pi Zero 吧。

另外,無法正常驅動 SPI 的 LCD,使用 Pi One 的則可以。

後來把 config/boards/orangepizero.csc 參照 orangepione.conf 修改,把沒用到的也刪掉。

# Allwinner H2+ quad core 256/512MB RAM SoC WiFi SPI
BOARD_NAME="Orange Pi Zero"
BOARDFAMILY="sun8i"
BOARD_MAINTAINER=""
BOOTCONFIG="orangepi_zero_defconfig"
#MODULES_CURRENT="g_serial"
MODULES_BLACKLIST="sunxi_cedrus"
# DEFAULT_OVERLAYS="usbhost2 usbhost3 tve"
# DEFAULT_CONSOLE="both"
# HAS_VIDEO_OUTPUT="yes"
# SERIALCON="ttyS0,ttyGS0"
KERNEL_TARGET="legacy,current,edge"
KERNEL_TEST_TARGET="current"
# CRUSTCONFIG="orangepi_zero_defconfig"

執行建立 image 的指令

./compile.sh \

BOARD=orangepizero MAKE_THREADS=8  \

BRANCH=edge RELEASE=noble \

BUILD_MINIMAL=yes BUILD_DESKTOP=no  \

NETWORKING_STACK="network-manager" \

KERNEL_CONFIGURE=no

後記,關於無法 reboot

將解決辦法反應在 git 上,維護者把 APM (advanced powered management,aka CRUST firmware) 拿掉了。但下載的 image 仍是舊的,使用者可在安裝更新後,使用 armbian-install 更新 u-boot。

連接 SPI 界面 LCD

Pi Zero 的界面接腳如下。

先用 gpioinfo 確認已使用的 pin。"r_pio 0 10" 為 PL10,是控制核心用的。

--------------
gpiochip0 - 224 lines:
line  17:      PA17    "orangepi:red:status" output active-high [used]
line  20:      PA20    "reg-vcc-wifi"        output active-high [used]
line 166:      PF06    "cd"                  input  active-low  [used]
line 204:      PG12    "usb0_id_det"         input  active-high [used]
gpiochip1 - 32 lines:
line   6:      PL06    "vdd-cpux"            output active-high [used]
line   7:      PL07    "reset"               output active-low  [used]
line  10:      PL10    "orangepi:green:pwr"  output active-high [used]
--------------

觸控屏

--------------
OPi Zero wiring:
Pin 23 - PA14 <-->  SPI1 SCK       & T_CLK
Pin 21 - PA16 <-->  SPI1 SDO<MISO> & T_DO      * LCD 的 MISO 不要接
Pin 19 - PA15 <-->  SPI1 SDI<MOSI> & T_DIN
Pin 31 - PA3  <-->  DC
Pin 33 - PA0  <-->  RESET
Pin 29 - PA10 <-->  LED
Pin 35 - PA13 <-->  LCD CS   
Pin 26 - PA18 <-->  T_CS
Pin 28 - PA19 <-->  T_IRQ
Pin 1  - 3.3V  (or Pin 4 - 5V)
Pin 6  - GND
--------------
* LCD 的 MISO 不用接,接了可能使得觸控失效。

ZSWAP 設定

記憶體 256MB,實在太少了,要使用實體的 SD 卡當 SWAP 才行。

在完成第一次啟動後,使用 gparted 修改分割區,留多一點空間給 swap。然後用 blkid 取得 swap 的 uuid,在 /etc/fstab 中加入 swap 設定。

UUID=f454716c-ed0b-4d43-bff5-93545b4ef388 none swap sw 0 0 

修改 /etc/default/armbian-zram-config,將 SWAP=false 的註解取消,然後重啟系統即可。

安裝 klipper

複製 kiauh 專案

$ git clone https://github.com/dw-0/kiauh

再執行 kiauh/kiauh.sh 安裝 klipper。

另外,由於記憶體較小,導致 tmpfs 的 /tmp 不足,在安裝 Moonraker 的階段,會耗盡 /tmp 的空間。因此需另建一個暫時的 tmp,步驟如下。

$ # Create a temp folder on a disk that has a lot of space:
sudo mkdir -p /bigtmp

# Set generous access to the temp folder:
sudo chmod 777 /bigtmp

# Change TMPDIR env to the big folder you just created:
export TMPDIR=/bigtmp

# install package

在安裝 Moonraker 時,改成用此暫時的 tmp。安裝其他的套件,則用 tmpfs,會比較快。另外,安裝 Moonraker 時,要在 putty 的 console 上執行。要是透過 ssh 安裝,會時間太久沒反應,裝到一半被踢出連線。






2025年7月27日 星期日

如何 mount Armbian 的 .img 檔

 Gemini 的回答


Mounting an Armbian .img file on Linux using a loop device is a very common task, typically done to inspect, modify, or extract files from the image before flashing it to an SD card.

Armbian images (like most single-board computer OS images) are usually disk images containing multiple partitions (e.g., a small boot partition and a larger root filesystem partition). Therefore, you need to expose these individual partitions from the .img file and mount them separately.

Here's a step-by-step guide on how to do it:


Prerequisites:

  1. Armbian .img file: Make sure you have the .img file. If it's compressed (e.g., .img.xz, .img.gz), you need to decompress it first.

    • Decompress .xz: unxz your_armbian_image.img.xz

    • Decompress .gz: gunzip your_armbian_image.img.gz

  2. Required Tools: Most Linux distributions have these pre-installed or readily available.

    • losetup: For creating and managing loop devices.1

    • mount: For mounting filesystems.

    • fdisk (or parted): For inspecting partition tables.2

    • sudo: For elevated privileges.3


Step-by-Step Guide:

1. Create Mount Points

You'll need separate directories on your host system where you want to mount the partitions from the image. A typical Armbian image has at least two partitions: a boot partition (often FAT32) and a root filesystem partition (often Ext4).

Bash
sudo mkdir -p /mnt/armbian_boot
sudo mkdir -p /mnt/armbian_rootfs

You can choose any path you prefer, but /mnt/ is a common convention for temporary mounts.

2. Attach the Image to a Loop Device and Expose Partitions

This is the most crucial step. Modern Linux kernels (and losetup versions) can automatically scan for partitions within a disk image.

Bash
sudo losetup -P --find --show your_armbian_image.img
  • sudo: Required for losetup as it interacts with kernel devices.

  • your_armbian_image.img: Replace this with the actual path to your Armbian .img file.

  • -P (or --partscan): This tells losetup to scan the image for partitions and automatically create separate loop devices for each partition found (e.g., /dev/loop0p1, /dev/loop0p2).

  • --find: Finds the first available (unused) loop device.

  • --show: Prints the name of the main loop device it used (e.g., /dev/loop0). Make a note of this device, as you'll need it for detaching later.

Example Output:

If it outputs /dev/loop0, then you should now have /dev/loop0p1 and /dev/loop0p2 (or more, depending on the image) available as distinct partition devices. You can verify this with:

Bash
ls -l /dev/loop0p*

You should see entries like /dev/loop0p1 and /dev/loop0p2.

3. Inspect Partition Types (Optional but Recommended)

Before mounting, you can quickly check the filesystem type of each partition to ensure you use the correct mount options (though mount is often smart enough to auto-detect).

Bash
file -s /dev/loop0p1
file -s /dev/loop0p2

Expected Output (example):

  • /dev/loop0p1: DOS/MBR boot sector, code offset 0x52+2, OEM-ID " mkfs.fat", sectors/cluster 8, root entries 512, Media descriptor 0xf8 (hard disk), sectors 524288 (volumes < 32 MB), FAT (32 bit), LBA, label "boot", serial id 0x12345678

    • This indicates a FAT32 (often shown as vfat) filesystem, which is typical for the boot partition.

  • /dev/loop0p2: Linux rev 1.0 ext4 filesystem data, UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (extents) (large files) (huge files) (dir_nlink) (extra isize) (metadata_csum)

    • This indicates an Ext4 filesystem, typical for the root filesystem.

4. Mount the Partitions

Now, mount the individual partitions to your created mount points.

Bash
# Mount the boot partition (usually FAT32)
sudo mount /dev/loop0p1 /mnt/armbian_boot

# Mount the root filesystem partition (usually Ext4)
sudo mount /dev/loop0p2 /mnt/armbian_rootfs
  • If mount complains about a wrong fs type, you might need to specify it explicitly:

    • sudo mount -t vfat /dev/loop0p1 /mnt/armbian_boot

    • sudo mount -t ext4 /dev/loop0p2 /mnt/armbian_rootfs

5. Access and Modify Files

You can now navigate into the mounted directories and access/modify files as needed.

Bash
ls /mnt/armbian_boot
ls /mnt/armbian_rootfs
cd /mnt/armbian_rootfs
# ... make your changes ...

6. Unmount the Partitions and Detach the Loop Device

This is a critical step to avoid data corruption. Always unmount the partitions and detach the loop device gracefully before removing the image file or doing anything else with it.

Bash
# Unmount the partitions first
sudo umount /mnt/armbian_boot
sudo umount /mnt/armbian_rootfs

# Detach the main loop device (replace /dev/loop0 with the actual device from step 2)
sudo losetup -d /dev/loop0

Alternative (Older/Less Common for Multi-Partition Images): kpartx

If losetup -P doesn't work for some reason (e.g., very old kernel), kpartx is an alternative.

  1. Install kpartx:

    Bash
    sudo apt install kpartx # For Debian/Ubuntu
    # sudo pacman -S kpartx # For Arch Linux
    
  2. Create device mapper entries:

    Bash
    sudo kpartx -av your_armbian_image.img
    

    This will output lines showing where it created mappings, e.g., /dev/mapper/loop0p1, /dev/mapper/loop0p2.

  3. Mount: Use these /dev/mapper/ devices to mount:

    Bash
    sudo mount /dev/mapper/loop0p1 /mnt/armbian_boot
    sudo mount /dev/mapper/loop0p2 /mnt/armbian_rootfs
    
  4. Unmount and remove mappings:

    Bash
    sudo umount /mnt/armbian_boot
    sudo umount /mnt/armbian_rootfs
    sudo kpartx -d your_armbian_image.img
    

By following these steps, you can effectively access and modify the contents of your Armbian disk image.


實例:

$ sudo losetup -P --find --show Armbian_25.5.1_Orangepione_noble_current_6.12.23_minimal.img
/dev/loop0

$ ls -l /dev/loop0p*
brw-rw---- 1 root disk 259, 12  7月 28 09:15 /dev/loop0p1

$ sudo file -s /dev/loop0p1
/dev/loop0p1: Linux rev 1.0 ext4 filesystem data, UUID=1dcda12f-cc77-431b-b193-4e4e56d8afd1, volume name "armbi_root" (extents) (64bit) (large files) (huge files)

$ sudo mount /dev/loop0p1 /mnt/pi-one 
# mount 另一個
$ sudo losetup -P --find --show Armbian_25.5.1_Orangepizero_noble_current_6.12.23_minimal.img
/dev/loop2
$ ls -l /dev/loop2p*
brw-rw---- 1 root disk 259, 14  7月 28 09:22 /dev/loop2p1
$ sudo file -s /dev/loop2p1
/dev/loop2p1: Linux rev 1.0 ext4 filesystem data, UUID=59dbad79-6dbe-433d-b8e1-c4304d8c6f3f, volume name "armbi_root" (extents) (64bit) (large files) (huge files)
$ sudo mount /dev/loop2p1 /mnt/pi-zero/

umount:

$ $ sudo umount /dev/loop0p1
$ sudo umount /dev/loop2p1
$ sudo losetup -d /dev/loop0
$ sudo losetup -d /dev/loop2

u




網誌存檔