參考 https://github.com/grblHAL/core/wiki/Compiling-GrblHAL
git clone --recurse-submodules https://github.com/grblHAL/STM32F4xx.git
參考 https://github.com/grblHAL/core/wiki/Compiling-GrblHAL
git clone --recurse-submodules https://github.com/grblHAL/STM32F4xx.git
參考
從淘寶買了製作 PCB 的套件,放了好久, 一直沒用。到後來,蝕刻劑受潮,還把附的銅箔板腐蝕掉一大塊。直到最近,為了使用 FPC軟排線連接 Orange Pi 和 SPI LCD,只能使用 FPC 插座轉接板,要用手焊接很多線,不好看,板子又大。才認真考慮製作 PCB。
淘寶買的感光藍油,可以很方便製作感光銅箔板,成本也低。不便之處,要用透明膠膜印出 PCB負片,才能曝光。後來,在網頁上無意中發現,有人用光固化3D印表機當 PCB 的曝光機,效果不錯。剛好手邊有光固化機器,一直沒用,賣又不值錢,正好可以拿來用。
開始學習使用 KiCad 軟體,使用 KiCad PCB 編輯器,手工畫 PCB。PCB 畫好後,使用 [繪製] 功能輸出 pdf。
KiCad 輸出的 pdf,再用 InkScape 開啟,先在 [文件屬性] 中,將格式由 [px] 改成 [mm],會自動改變縮放比例。再另存成 SVG檔,這樣圖才不會變大。KiCad 也能直接輸出 SVG檔,但解析度有問題,會太低。
然後,使用 OpenScad 匯入 SVG檔,轉成有高度的 STL 檔,才能給光固化用。這個步驟,會有一個小問題,pad 的中空鑽孔,都被填滿了,看了很不習慣。在 OpenScad,要另外再加工一下,挖出那些孔。
使用 CHITUBOX (赤兔) 切片軟體,將產生的 STL 檔,產生切片檔,再 copy 到 USB碟,用光固化機器曝光。切片參數,首層的時間,改成想要的曝光時間,大約為 60秒左右。首層曝光完,就可以關掉,後面的不用跑了。
下圖是顯示的曝光在白紙上的情形,用來定位用。
顯影後的電路板
在 Orange Pi One 上安裝 CNCJS
參考
官方文件的資訊,已嚴重落後,如支援的 Node.js 的版本為 v4。目前透過 npm 安裝的 cncjs 是 1.10.5,在 github 的 package.json 中,要求的 Node.js 是 ">=18"。
"engines": {
"node": ">=18"
},安裝 "Node Version Manager" 來管理多個 Node.js 版本。
# 安裝 nvm
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
$ source .profile
$ source .bashrc
#安裝最新的 node.js
$ nvm install 22
$ nvm use 22
# 執行 node 會出現錯誤
# node: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory
$ sudo apt install libatomic1
# 更新 npm
$ npm install npm@latest -g
# 安裝 cncjs
$ npm install -g cncjs
# 更新 cncjs
$ npm install -g cncjs@latest以上的安裝,只能以個人的身分執行。
執行後,在網頁上看到的畫面。
# 設定網路之後,更新系統
$ sudo apt update
$ sudo apt upgrade
# 安裝所需套件及 cncjs
$ sudo apt install nodejs npm git
$ sudo npm install -g cncjs --unsafe-perms
# CNCjs Test Run
$ cncjs --allow-remote-access -p 8080
# give us permissions to run on port 80 without root
$ sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/node
# give permissions to use the serial port
$ sudo usermod -a -G dialout cncjs
# 建立及啟動 CNCjs Systemd Service
$ sudo touch /etc/systemd/system/cncjs.service
$ sudo chmod 664 /etc/systemd/system/cncjs.service
$ sudo nano /etc/systemd/system/cncjs.service
$ sudo systemctl daemon-reload
$ sudo systemctl start cncjs
$ sudo systemctl enable cncjs
# 下載 tinyweb 套件
$ cd ~
$ git clone https://github.com/cncjs/cncjs-pendant-tinyweb
建立 /etc/systemd/system/cncjs.service 如下。
[Unit]
Description=CNC Controller Web UI
After=network-online.target
[Service]
ExecStart=cncjs -p 80 -m /tinyweb:/home/cncjs/cncjs-pendant-tinyweb/src
User=cncjs
WorkingDirectory=/home/cncjs
Restart=always
[Install]
WantedBy=multi-user.target 設定 tinyweb
enable 的 service,連結放在 /etc/systemd/system/multi-user.target.wants
安裝所需的 X window 的 package。
sudo apt install xinit xinput x11-xserver-utils \
xserver-xorg-input-evdev xserver-xorg-input-libinput \
xserver-xorg-legacy xserver-xorg-video-fbdev \
xdg-utils chromium-browser 修改 /etc/X11/Xwrapper.config,"allowed_users=anybody"
cncjs -m /tinyweb:/home/klipper/cncjs-pendant-tinyweb-1.2.4/src &
執行 xinit ./start_tinyweb.sh。
進入 [Settings] (齒輪圖示) 功能,到 [Commands] 頁面,點選 [+ New],在 title 中輸入 "Shutdown",以及在 [command] 欄位輸入 "sudo shutdown -h now"。
賦予 shutdown 權限,執行 "sudo visudo" 指令,新增一面的內容
在網路上有人賣淘汰的 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遍,甚至不小心用洗板液急速冷卻,仍然正常運作。
現在的記憶體晶片都是 BGA 封裝,雖然買來的記憶體晶片,都已植錫,但焊接失敗,就必須拆下,重新植錫,再次焊接。因此,在焊接前,先把 BGA 的植錫和焊接功夫練好。翻找手邊的剩餘材料,發現 DDR2 的記憶模組是使用 BGA 封裝的晶片,現在又已用不上,正好用來練習。花了一個多星期時間練習,拆裝了幾條記憶模組,十幾顆晶片,慢慢掌握其中的技巧。
可以買記憶體用的小鋼網。雖然有買簡易植錫架,但後來在網路上看到有人分享的經驗,發現這樣做更好。先徒手植 2顆上去,當作鋼網的定位點,這樣就不需使用植錫架。
徒手植錫,要練一下。練成後,不用鋼網,也可以用手排錫球,植錫。但實在很費時間,只能當練功。關鍵在於,塗上薄薄一層助焊膏,可以黏住錫球。太多助焊膏,助焊膏一化開,錫球會漂走。熱風槍的風速開到最小,先用遠一點的距離吹,讓錫球先黏在焊盤上,再靠近吹,讓它整個化開,完美地吸在焊盤上。
在焊盤上均勻塗抹助焊膏,一定要用助焊膏,錫球才能黏在焊盤上。這很關鍵,不能太少,不然錫球都會黏在鋼網上。但也不能太多,不然錫球會飄。再把鋼網套上,背後可以用鋁箔紙貼住。
用鑷子一顆一顆把錫球放上去。利用助焊膏黏性,把球黏在鑷尖,再黏到焊盤上。
錫球全部擺好後,用熱風槍,380度,慢慢吹。看影片,都是 40幾秒就好。但我就是要吹到 2分鐘以上才行,不知差在那裡。但也發現,用這溫度吹個 3分鐘多,晶片也還可以正常工作,就放心地做吧。
植球和焊接,最好有計時器,不要光憑感覺。要有耐心,常要好幾分鐘,時間不夠,錫沒全化,硬來,只會把東西弄壞,更麻煩。
拆焊,可以用 450度。PCB上的塑膠零件,用鋁箔紙保護一下,以免吹壞。注意一下小零件,不要不小心把它吹飛或撞飛。若真不幸弄飛了,要留下來,事後再焊回去。一定要等錫全化了,再把晶片夾起來,一次就要拿起來。若不幸一次不成,部分黏住,不要硬拔,會把焊盤拔壞。
再來就是把晶片焊回去,用 380度,我要吹到 3分鐘,才能焊接成功。先對 PCB 吹個一分鐘,上助焊膏,碰到就化開,可以塗抹均勻。
買來的晶片,可能不是新品,但都有植錫。可惜,我直接焊接,都會失敗。反倒是我自己植錫的,吹個 2分鐘 ~ 3分鐘,就能自動歸位。不知是不是 有鉛 和 無鉛 的差別。後來乾脆全部重新植錫再焊,比較不會失敗。
另外,影片的經驗分享,都是用鑷子輕推一下,會重新歸位,判斷錫全化呈流動狀態,為焊接成功的判斷。但手抖得厲害,一不小心就推到位置之外,也看不出塌陷的瞬間。後來發現有個影片,晶片擺得不正,錫全化呈流動狀態時,晶片自動歸正了。
我就在放晶片時,對準位置之後,稍稍把它弄歪一點,讓晶片邊緣和定位白線不會對齊。等加熱到晶片和白線對齊,就成功了。
後來,發現可以吹到 3分鐘,晶片仍是正常的,在重新植錫後,就固定吹個 3分鐘,比較保險。
好不容易,成功了,升級為 1GB 的記憶體。
在 Klipper 的 LCD 的功能表中,增加一些功能,方便使用。
在 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
在網路上有人出清二手的 Orange Pi Zero,雖然是十多年前的產品,但拿來當 Klipper 的上位機還蠻適合的。
Orange Pi Zero 和 Orange Pi One 類似,但有 wifi,不用再另外花錢買 wifi 裝置。另外,只有一個 DRAM 晶片,因此記憶體最大只有 512MB,預設是 256MB。使用 H2+ CPU,是 H3 CPU 的閹割版,但對 klipper 的運作影響不大。
賣家出貨,512MB 和 256MB,隨機出貨,256MB 的板子比較多。
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
將解決辦法反應在 git 上,維護者把 APM (advanced powered management,aka CRUST firmware) 拿掉了。但下載的 image 仍是舊的,使用者可在安裝更新後,使用 armbian-install 更新 u-boot。
在 Armbian 系統中,可以透過執行以下指令來查看系統狀態,其中通常包含了 CPU 溫度:
$ armbianmonitor -m
$ cat /sys/class/thermal/thermal_zone0/temp
$ cat /etc/armbianmonitor/datasources/soctemp
退出監控: 按下 Ctrl + C 即可退出。
Pi Zero 的界面接腳如下。
先用 gpioinfo 確認已使用的 pin。"r_pio 0 10" 為 PL10,是控制核心用的。
觸控屏
使用 evtest 測試觸控功能。
要把 /boot/armbianEnv.txt 的 tve (Composite TV Encoder) 的 overlay 取消掉,console 才會輸出到 LCD。
使用 panel-mipi-dbi-spi 的驅動,會載入 /usr/lib/firmware 目錄下的 panel-mipi-dbi-spi.bin。這樣對應不同驅動的 LCD,只要更換 panel-mipi-dbi-spi.bin 就好。因為檔名是固定的,為了區分使用那種驅動,以連結來建立該檔案。
設定檔 lcd_mipi_st7796s.dts。
/dts-v1/;
/plugin/;
/ {
compatible = "xunlong,orangepi-zero", "allwinner,sun8i-h2-plus";
fragment@0 {
target = <&spi1>;
__overlay__ {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins>;
cs-gpios = <&pio 0 3 0>, <&pio 0 13 0>; /* PA3 PA13 */
panel: panel@0 {
#compatible = "sainsmart18","panel-mipi-dbi-spi";
compatible = "panel-mipi-dbi-spi";
reg = <0>; /* Chip Select 0 */
// 頻率不能太高,螢幕會花
spi-max-frequency = <25000000>;
rotation = <270>;
reset-gpios = <&pio 0 19 0>; /* RESET=PA19 */
dc-gpios = <&pio 0 18 0>; /* DC_RS=PA18 */
// backlight-gpios = <&pio 2 8 0>; /*LED=PC5*/
backlight = <&backlight_gpio>;
debug = <4>;
// st7796s firmware
width-mm = <84>;
height-mm = <56>;
write-only;
panel-timing {
// st7796s
hactive = <480>; // width
vactive = <320>; // height
hback-porch = <0>;
vback-porch = <0>;
clock-frequency = <0>;
hfront-porch = <0>;
hsync-len = <0>;
vfront-porch = <0>;
vsync-len = <0>;
};
};
ads7846: ads7846@0 {
compatible = "ti,ads7846";
reg = <1>; /* Chip Select 1 */
// 頻率不用太高,可以工作就好
spi-max-frequency = <500000>;
interrupt-parent = <&pio>;
// IRQ PA10
interrupts = <0 10 2>; /* PC15 IRQ_TYPE_EDGE_FALLING */
pendown-gpio = <&pio 0 10 1>; /* ACTIVE HIGH */
/* ti,swap-xy = <0x1>; */
ti,x-min = /bits/ 16 <0>;
#ti,x-min = /bits/ 16 <0x016F>;
ti,y-min = /bits/ 16 <0>;
ti,x-max = /bits/ 16 <0x0FFF>;
#ti,x-max = /bits/ 16 <0x0F2A>;
ti,y-max = /bits/ 16 <0x0FFF>;
ti,pressure-min = /bits/ 16 <0>;
ti,pressure-max = /bits/ 16 <0xFFFF>;
ti,x-plate-ohms = /bits/ 16 <400>;
};
};
};
fragment@1 {
target-path = "/";
__overlay__ {
backlight_gpio: backlight_gpio {
compatible = "gpio-backlight";
gpios = <&pio 0 2 0>; /* LED=PA2 */
default-on;
};
};
};
};
執行 "armbian-add-overlay lcd_mipi_st7796s.dts",即可編譯設定檔。
和 MKS Pi 或 Fly Pi 比起來,使用 Orange Pi,麻煩的地方是要自己想辦法整合 LCD。後來自己用 FPC轉接板做,成品如圖,雖然不好看,還算堪用。
記憶體 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 的註解取消,然後重啟系統即可。
後來自己練習 BGA 焊接,把記憶體改成 1GB,就不用擔心 temp 空間不夠的問題了。
複製 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 安裝,會時間太久沒反應,裝到一半被踢出連線。
To connect to a /dev/ttyUSB0 device using PuTTY in Linux, you typically need to add your user account to the dialout group, which has default read/write permissions for serial ports.
設定好 NetworkManager 後,若沒有停掉 netplan 和 systemd-networkd,開機會要等 3分鐘才完成。
作法如下。
$ sudo systemctl disable --now systemd-networkd.service systemd-networkd.socket systemd-networkd-wait-online.service
$ sudo systemctl restart NetworkManager
$ sudo systemctl mask systemd-networkd-wait-online.service
$ sudo apt purge netplan netplan.io -y回傳訊息如下,不知會有何問題。
修改 /etc/netplan/armbian.yaml,如下。
network:
version: 2
renderer: NetworkManager可以使用 systemd-analyze 產生時間圖,看看開機卡在那裡
$ systemd-analyze plot > systemd-analyze.svg 由圖檔知道,一開始,kenerl 載入花了 5秒,systemd 程式載入用了 2秒,之後才開始啟動各種服務。
Unexpected error: Scanning not allowed while unavailable
為了方便 PCB 佈線,連接更改如下
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:
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
Required Tools: Most Linux distributions have these pre-installed or readily available.
losetup: For creating and managing loop devices.
mount: For mounting filesystems.
fdisk (or parted): For inspecting partition tables.
sudo: For elevated privileges.
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).
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.
This is the most crucial step. Modern Linux kernels (and losetup versions) can automatically scan for partitions within a disk image.
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:
ls -l /dev/loop0p*
You should see entries like /dev/loop0p1 and /dev/loop0p2.
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).
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.
Now, mount the individual partitions to your created mount points.
# 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
You can now navigate into the mounted directories and access/modify files as needed.
ls /mnt/armbian_boot
ls /mnt/armbian_rootfs
cd /mnt/armbian_rootfs
# ... make your changes ...
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.
# 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
kpartxIf losetup -P doesn't work for some reason (e.g., very old kernel), kpartx is an alternative.
Install kpartx:
sudo apt install kpartx # For Debian/Ubuntu
# sudo pacman -S kpartx # For Arch Linux
Create device mapper entries:
sudo kpartx -av your_armbian_image.img
This will output lines showing where it created mappings, e.g., /dev/mapper/loop0p1, /dev/mapper/loop0p2.
Mount: Use these /dev/mapper/ devices to mount:
sudo mount /dev/mapper/loop0p1 /mnt/armbian_boot
sudo mount /dev/mapper/loop0p2 /mnt/armbian_rootfs
Unmount and remove mappings:
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/loop2u