一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Linux|Centos|Ubuntu|系統進程|Fedora|注冊表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服務器之家 - 服務器系統 - Ubuntu - Hi3798MV200 恩兔N2 NS-1 (三): 制作 Ubuntu rootfs

Hi3798MV200 恩兔N2 NS-1 (三): 制作 Ubuntu rootfs

2023-11-12 07:05未知服務器之家 Ubuntu

Hi3798MV200 恩兔N2 NS-1 (三): 制作 Ubuntu rootfs 如果把整個Linux操作系統看作層級關系, 根文件系統是位于內核之上的模塊,對于同樣的硬件和架構, Linux各個發行版的區別主要在于根文件系統, 而底層的內核部分幾乎是一樣的. 通過制作根文

Hi3798MV200 恩兔N2 NS-1 (三): 制作 Ubuntu rootfs

如果把整個Linux操作系統看作層級關系, 根文件系統是位于內核之上的模塊,對于同樣的硬件和架構, Linux各個發行版的區別主要在于根文件系統, 而底層的內核部分幾乎是一樣的. 通過制作根文件系統, 可以更換成其它發行版, 定制自己的最小化安裝.

目錄

  • Hi3798MV200 恩兔N2 NS-1 (一): 設備介紹和刷機說明
  • Hi3798MV200 恩兔N2 NS-1 (二): HiNAS海納思使用和修改
  • Hi3798MV200 恩兔N2 NS-1 (三): 制作 Ubuntu rootfs
  • Hi3798MV200 恩兔N2 NS-1 (四): 制作 Debian rootfs

關于根文件系統 rootfs

在 Linux 中, 所有的文件和目錄被組織成一個樹狀的結構, 而根文件系統, rootfs, the root filesystem, 位于文件樹的頂層(路徑'/'). Linux 內核通過 root = 設置的參數掛載 rootfs. 在根文件系統中也包含了其它文件樹的掛載點(mount points), 用于將其它文件(設備)掛載到當前環境中, 形成完整的系統.

在根文件系統中包含了用于系統啟動和操作的關鍵文件. 系統引導啟動程序會在根文件系統掛載之后執行初始化腳本(如rcS, init.d, profile).

如果把整個Linux操作系統看作層級關系, 根文件系統是位于內核之上的模塊,對于同樣的硬件和架構, Linux各個發行版的區別主要在于根文件系統, 而底層的內核部分幾乎是一樣的. 通過制作根文件系統, 可以更換成其它發行版, 定制自己的最小化安裝.

文件準備

底包

本例使用的是稍息版 Debian 10, 替換成 Ubuntu20.04.

從 stretch.tar.bz2 中提取驅動部分, 位于 /lib/modules/4.4.35-hi3798mv2x/

下載 ubuntu-base

從國內鏡像站點, 下載 ubuntu-base 包

  • https://mirrors.ustc.edu.cn/ubuntu-cdimage/ubuntu-base/releases/
  • https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cdimage/ubuntu-base/releases/

解壓

在本地創建工作目錄, 將壓縮包解壓到工作目錄下, 注意要用 sudo + -p(-p, --preserve-permissions)參數, 保留原owner和原權限

mkdir workroot
sudo tar -xpf ubuntu-base-20.04.5-base-arm64.tar.gz -C workroot/

初始的目錄大小為77MB左右. 可以檢查一下 workroot 下的文件目錄, owner是否為 root.

關于為什么要用 sudo

Even if you use tar's --same-owner flag, you will still need to extract the files as root to preserve ownership.
--same-owner flag is on by default for root.
--no-same-owner, extract files as yourself, which is default for ordinary users

準備 resolv.conf

base系統中 resolv.conf 為空, 需要設置 nameserver 否則 chroot 后目標系統 apt install 時無法解析域名

選項一, 復制

復制 resolv.conf 到目標系統

sudo cp /etc/resolv.conf workroot/etc/resolv.conf

選項二, 直接寫

echo "nameserver 127.0.0.53" | sudo tee workroot/etc/resolv.conf

復制 qemu-xxx-static

安裝 qemu-user-static, 這個包里面有各個架構的二進制執行文件, 會安裝到 /usr/bin

sudo apt install qemu-user-static

對于 armhf, 復制 qemu-arm-static; 對于 arm64 復制 qemu-aarch64-static

# armhf
sudo cp /usr/bin/qemu-arm-static workroot/usr/bin/
# arm64
sudo cp /usr/bin/qemu-aarch64-static workroot/usr/bin/

在進行下一步之前檢查文件格式是否正確, 32位的 armhf 用 qemu-arm-static, 64位的 arm64 用 qemu-aarch64-static

# armhf
sudo chroot workroot/ /usr/bin/qemu-arm-static /bin/ls
# arm64
sudo chroot workroot/ /usr/bin/qemu-aarch64-static /bin/ls

如果文件架構不匹配, 會提示- /bin/ls: Invalid ELF image for this architecture

修改目標系統軟件源

vi workroot/etc/apt/sources.list

替換為USTC源

: %s/http:\/\/ports.ubuntu.com\/ubuntu-ports\//http:\/\/mirrors.ustc.edu.cn\/ubuntu-ports\//gc

掛載目標系統

選項一: 手工掛載

掛載目錄

sudo mount -t proc /proc    workroot/proc
sudo mount -t sysfs /sys    workroot/sys
sudo mount -o bind /dev     workroot/dev
sudo mount -o bind /dev/pts workroot/dev/pts

切換根目錄

sudo chroot workroot/

如果前面的檢查沒問題, 但是這一步總是提示 '/bin/bash': Exec format error, 檢查一下 binfmts 是否開啟

update-binfmts --display

正常應該顯示如下, 對應格式為 enabled,

qemu-aarch64 (enabled):
     package = qemu-user-static
...
qemu-arm (enabled):
     package = qemu-user-static
...

如果顯示為 disabled, 需要檢查是否有軟件未安裝. 安裝了 Docker 的 Ubuntu 環境可能會有沖突.

$ mount | grep binfmt
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=29,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=18150)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,nosuid,nodev,noexec,relatime)

選項二: 使用腳本掛載

以上的操作, 可以通過一個腳本進行簡化

#!/bin/bash
mnt() {
    echo "MOUNTING"
    sudo mount -t proc /proc    ${2}proc
    sudo mount -t sysfs /sys    ${2}sys
    sudo mount -o bind /dev     ${2}dev
    sudo mount -o bind /dev/pts ${2}dev/pts
    sudo chroot ${2}
}
umnt() {
    echo "UNMOUNTING"
    sudo umount ${2}proc
    sudo umount ${2}sys
    sudo umount ${2}dev/pts
    sudo umount ${2}dev
}

if [ "$1" == "-m" ] && [ -n "$2" ] ;
then
    mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ];
then
    umnt $1 $2
else
    echo ""
    echo "Either 1'st, 2'nd or both parameters were missing"
    echo ""
    echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
    echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
    echo ""
    echo "For example: ch-mount -m /media/sdcard/"
    echo ""
    echo 1st parameter : ${1}
    echo 2nd parameter : ${2}
fi

需要使用目標系統環境時

./mount.sh -m workroot/

定制 rootfs 內容

root@Box:/# uname -a
Linux Box 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
# 檢查 mount
root@Box:/# mount
/proc on /proc type proc (rw,relatime)
/sys on /sys type sysfs (rw,relatime)
udev on /dev type devtmpfs (rw,nosuid,noexec,relatime,size=6965676k,nr_inodes=1741419,mode=755,inode64)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)

添加驅動文件

僅使用kernel自帶的驅動可以啟動rootfs, 但是一些板載的外設, 例如SATA硬盤和USB, 會因為沒有驅動而無法識別. 需要手動將這些驅動放到rootfs中.

通過uname -r可以看到目標系統的架構為4.4.35-hi3798mv2x, 由此可以確定驅動的路徑為

/lib/modules/4.4.35-hi3798mv2x/

從前面準備的底包中, 將驅動部分文件提取后放到這個目錄下, 結構類似于

modules
└── 4.4.35-hi3798mv2x
    ├── kernel
    │?? ├── crypto
    │?? ├── drivers
    │?? ├── fs
    │?? ├── lib
    │?? └── net
    ├── modules.alias
    ├── modules.alias.bin
    ├── modules.builtin
    ├── modules.builtin.alias.bin
    ├── modules.builtin.bin
    ├── modules.dep
    ├── modules.dep.bin
    ├── modules.devname
    ├── modules.order
    ├── modules.softdep
    ├── modules.symbols
    └── modules.symbols.bin

安裝基礎軟件

# 77M -> 300M
apt update
# 300M -> 304M
apt install nano sudo vim-tiny

修改軟件源vi /etc/apt/sources.list, 替換為USTC源

: %s/http:\/\/ports.ubuntu.com\/ubuntu-ports\//http:\/\/mirrors.ustc.edu.cn\/ubuntu-ports\//gc

再安裝其它軟件就快多了

apt upgrade
# 304M -> 440M
apt install openssh-server
# 440M -> 445M
apt install u-boot-tools net-tools sysstat smartmontools network-manager

安裝的軟件包中

  • openssh-server 提供 ssh 服務
  • u-boot-tools 提供 fw_printenv 和 fw_setenv 方法, 用于修改 UBOOT 啟動參數
  • net-tools 提供 ifconfig, netstat 等常用工具
  • sysstat 提供 iostat 等常用工具

基礎設置

設置網絡

mkdir /etc/network/interfaces.d
echo auto eth0 > etc/network/interfaces.d/eth0
echo iface eth0 inet dhcp >> etc/network/interfaces.d/eth0

給 root 用戶設置密碼 注意 這一步別忘了

passwd

開啟 root 用戶 ssh 訪問, 編輯 /etc/ssh/sshd_config, 找到

#PermitRootLogin prohibit-password

替換為

PermitRootLogin yes

配置登錄的串口, 修改文件 /etc/systemd/system/getty.target.wants/[email protected]

vi /etc/systemd/system/getty.target.wants/getty\@tty1.service

ConditionPathExists=/dev/tty0

修改為實際的名稱

ConditionPathExists=/dev/ttyAMA0

清理文件

安裝完成后, 清理apt

apt autoremove
apt-get autoclean
apt-get clean
apt clean
# 結束后 368M

取消掛載目標系統

在目標系統上, exit 退出

結束后, 要先取消掛載

選項一: 手工取消掛載

sudo umount workroot/proc
sudo umount workroot/sys
sudo umount workroot/dev/pts
sudo umount workroot/dev

選項二: 通過腳本取消掛載

如果通過腳本, 則是

./mount.sh -u workroot/

制作 rootfs 鏡像文件

# 生成一個適當大小的空鏡像,這個大小參考du -h workroot
dd if=/dev/zero of=rootfs.img bs=1M count=1024
# 格式化 
mkfs.ext4 rootfs.img
# or
mkfs -t ext4 rootfs.img
# 掛載空鏡像
mkdir rootfs
sudo mount rootfs.img rootfs/
# 寫入文件, 保留權限
sudo cp -rfp workroot/* rootfs/
# 取消掛載
sudo umount rootfs/
# 檢查文件系統并自動修復
e2fsck -p -f rootfs.img
# 使鏡像緊湊
resize2fs -M rootfs.img

問題和解決

Root 能串口登錄, 無法 ssh 登錄

這是因為 ssh 默認禁止 root 登錄, 編輯 /etc/ssh/sshd_config, 找到

#PermitRootLogin prohibit-password

替換為

PermitRootLogin yes

然后systemctl restart sshd重啟 sshd 服務

分區可用空間為0

這是因為鏡像壓縮后寫入, 分區大小就是鏡像大小, 需要通過 resize2fs /dev/[partition] 擴充分區

方案一: 使用腳本, 手工執行

創建 /usr/bin/local_resize.sh, 內容如下, chmod +x 設為可執行

#!/bin/bash
rootfs_partition=/dev/$(lsblk -l|grep /|awk '{print $1}')
logger -t "resize-disk[$$]" "resizing $rootfs_partition"
if [ "$(echo $rootfs_partition | grep "mmc")" = "" ];then
    rootfs_disk=$(echo "$rootfs_partition" |sed -E -e 's/^(.*)[0-9]+/\1/g')
else
    rootfs_disk=$(echo "$rootfs_partition" |sed -E -e 's/^(.*)p[0-9]+/\1/g')
fi

if [ "$rootfs_disk" = "/dev/mmcblk0" ]; then
    resize2fs $rootfs_partition 2>&1 > /dev/null
else
    rootfs_partition_num=$(echo "$rootfs_partition" |sed -E -e 's/^.*([0-9]+)/\1/g')
    startfrom=$(fdisk -l ${rootfs_disk} -o device,start|grep ${rootfs_partition}|awk '{print $2}')
    (echo d; echo $rootfs_partition_num; echo n; echo p; echo $rootfs_partition_num; echo $startfrom; echo ; echo p; echo w;) | fdisk $rootfs_disk
    sync
    resize2fs $rootfs_partition
fi
logger -t "resize-disk[$$]" "resized $rootfs_partition"

方案二: 使用 systemd service 在第一次啟動時執行

增加 /usr/sbin/local-resize2fs.sh , chmod +x 設為可執行

#!/bin/bash
if [ ! -f /etc/first_init ]; then
    rootfs_partition=/dev/$(lsblk -l|grep /|awk '{print $1}')
    logger -t "resize-disk[$$]" "resizing $rootfs_partition"
    if [ "$(echo $rootfs_partition | grep "mmc")" = "" ];then
        rootfs_disk=$(echo "$rootfs_partition" |sed -E -e 's/^(.*)[0-9]+/\1/g')
    else
        rootfs_disk=$(echo "$rootfs_partition" |sed -E -e 's/^(.*)p[0-9]+/\1/g')
    fi

    if [ "$rootfs_disk" = "/dev/mmcblk0" ]; then
        resize2fs $rootfs_partition 2>&1 > /dev/null
    else
        rootfs_partition_num=$(echo "$rootfs_partition" |sed -E -e 's/^.*([0-9]+)/\1/g')
        startfrom=$(fdisk -l ${rootfs_disk} -o device,start|grep ${rootfs_partition}|awk '{print $2}')
        #lastsector=$(fdisk -l ${rootfs_disk} -o device,end|grep ${rootfs_partition}|awk '{print $2}')
        (echo d; echo $rootfs_partition_num; echo n; echo p; echo $rootfs_partition_num; echo $startfrom; echo ; echo p; echo w;) | fdisk $rootfs_disk
        sync
        resize2fs $rootfs_partition
    fi
    echo `date +%s%N` > /etc/first_init
    logger -t "resize-disk[$$]" "resized $rootfs_partition"
fi
exit 0

增加service: /etc/systemd/system/resize2fs.service

[Unit]
Description=resize2fs local filesystem
Before=local-fs-pre.target
DefaultDependencies=no

[Service]
Type=oneshot
TimeoutSec=infinity
ExecStart=/usr/sbin/local-resize2fs.sh
RemainAfterExit=true

[Install]
RequiredBy=local-fs-pre.target

在 /etc/systemd/system/local-fs-pre.target.wants/ 下面增加 resize2fs.service 的軟鏈, 使其生效

參考

  • https://wiki.t-firefly.com/en/ROC-RK3399-PC/linux_build_ubuntu_rootfs.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 婷射吧 | 国产亚洲欧美在线中文bt天堂网 | 极品丝袜老师h系列全文阅读 | 草莓污污| 动漫美女被吸乳羞羞小说 | 黑人chinese女人 | 好爽好深好猛好舒服视频上 | 男人女人性生活视频 | 青柠网在线观看视频 | 美女扒开胸罩露出奶 | 人与蛇boxxⅹ | 精品欧美一区二区在线观看欧美熟 | 亚洲成在人网站天堂一区二区 | 动漫美女被羞羞产奶 | 边摸边吃奶又黄激烈视频韩国 | 精品福利视频一区二区三区 | 9久热久爱免费精品视频在线观看 | 大乳女子一级毛片 | 九九热视频 这里有精品 | 亚洲激情婷婷 | 免费毛片| 涩涩屋在线观看 | 色噜噜狠狠色综合 | 青青草国产精品免费 | 韩国三级年轻小的胰子完整 | 91次元成年破解版 | 男同gay玩奴男同玩奴 | 九九久久国产精品大片 | 91九色porny国产美女一区 | 国产日韩一区二区三区 | 久久久久久免费高清电影 | 日本动漫啪啪动画片mv | 日本伊人色综合网 | 久久久久夜 | 国产精品videosse | 国产一区二区三区四 | 欧美在线视频一区在线观看 | 欧美伊人久久久久久久久影院 | 国产夜趣福利第一视频 | 亚洲天堂在线视频观看 | 午夜一区二区福利视频在线 |