Kevin's Blog https://linuxer.top/ zh-CN Talk is cheap. Show me the code. Wed, 04 Nov 2020 22:01:00 +0800 Wed, 04 Nov 2020 22:01:00 +0800 树莓派OpenCV-4.5.0镜像 https://linuxer.top/archives/opencv-raspi-img.html https://linuxer.top/archives/opencv-raspi-img.html Wed, 04 Nov 2020 22:01:00 +0800 kevin OpenCV是一个基于BSD许可发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

为了方便在树莓派上使用,我制作了一个OpenCV-4.5.0直刷镜像。

镜像说明

这个镜像是基于树莓派官方raspios-buster-arm64桌面版镜像制作,内核版本为5.4.72OpenCV版本为4.5.0,默认开启sshvnc,更换清华源,4B支持USB启动,第一次开机自动扩容。

兼容3B3B+4B

支持开机前配置wifi,方法和官方系统一样,在boot分区创建wpa_supplicant.conf文件。

根据需要配置一个或多个wifi连接信息,将ssidpassword替换为真实值即可。

示例:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=CN

network={
    ssid="无线ssid"
    psk="无线密码"
    key_mgmt=WPA-PSK
    priority=1
}

默认用户/密码:pi/raspberryroot用户没有启用,如果需要请自行开启。

默认swap大小为100M,如需修改,请编辑/etc/dphys-swapfile文件,修改CONF_SWAPSIZE=100,单位为MB,如果需要设置1G,则配置为CONF_SWAPSIZE=1024,保存文件执行sudo systemctl restart dphys-swapfile.service重启服务即可。

其他配置项可以通过sudo raspi-config进行设置,跟官方系统相同。

OpenCV信息:
opencv-4.5.0源码目录:/home/pi/opencv/opencv-4.5.0
opencv_contrib目录:/home/pi/opencv/opencv_contrib-4.5.0
构建目录:/home/pi/opencv/build
安装前缀:/usr/local

想自己折腾的同学也可以自己编译,在树莓派4B4G上编译大约需要2个小时,不想折腾的可以直刷这个镜像。

以下是几个python3的Demo在4B4G运行效果:

20201104184706.png

20201104185417.png

20201104185511.png

20201104185704.png

20201104190056.png

20201104191215.png

20201104191714.png

20201104192036.png

下载地址

下载地址:https://pan.baidu.com/s/1Et9M-iltupnsPgtzTzzqgw ,提取码:v65p

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
1 https://linuxer.top/archives/opencv-raspi-img.html#comments https://linuxer.top/feed/
树莓派安装双系统 https://linuxer.top/archives/raspi-dual-boot.html https://linuxer.top/archives/raspi-dual-boot.html Thu, 29 Oct 2020 08:24:00 +0800 kevin 玩树莓派的小伙伴可能遇到这样的烦恼,手里只有一张卡或者一块ssd,但是又想体验不同的系统,无奈只能重复的刷系统,可以说相当麻烦了,今天就说一说树莓派如何安装双系统。

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

前言

树莓派官方提供的NOOBS是可以实现多系统安装的,但是也存在一定的弊端,NOOBS本省会占用一定的空间造成空间浪费,系统都是从国外服务器在线下载,速度可想而知,而且需要显示器(从2015年开始玩pi的我到现在也没有显示器,穷啊),最主要的还是不符合玩家折腾的精神,所以我们不使用NOOBS,我们自己实现一个不需要显示器的双系统。

材料准备

  1. 树莓派4b
  2. SD卡一张(16G或以上),或硬盘一块
  3. 母-母杜邦线一条
  4. Linux操作系统(推荐Ubuntu),或者直接使用树莓派本身

SD卡或者USB都可以做双系统,我这里使用一张64G卡,操作系统我直接使用树莓派,如果你只有一张卡,那只能使用电脑或者虚拟机了。

安装

我选择的两个系统是官方系统和基地2.0,可以根据自己的需求更换。

0x00.准备工作

打开终端

#切换到root
sudo -i

#更新系统软件
apt update
apt upgrade

apt install dosfstools kpartx rsync

#创建工作目录
mkdir dualboot

cd dualboot

#创建挂载目录
mkdir boot root osimg

#上传两个要安装的系统镜像到这个目录
#2020-08-20-raspios-buster-armhf.img
#2020-06-22-OPENFANS-Debian-Buster-Desktop-Aarch64-ext4-v2020-2.0-U4-Release.img

20201029093230.png

0x01.分区

插卡,对介质进行分区和格式化
查看设备

lsblk

20201029093251.png
我这里设备名称是sda,根据自己情况替换

#分区
cfdisk /dev/sda

删除原有所有分区
20201029093648.png

创建三个分区,一个boot分区(fat32)512M,两个系统分区(ext4)

创建boot分区
20201029094035.png
20201029094103.png
20201029094122.png
20201029094152.png
20201029094216.png

创建第一个系统分区,我这里设置30G,大家根据自己需求设置
20201029094253.png
20201029094315.png
20201029094335.png

第二个系统分区创建同上

将改变写入磁盘
20201029094519.png
20201029094542.png

q退出cfdisk,检查磁盘分区

lsblk

20201029094616.png

格式化,注意替换自己的设备名称

#格式化boot分区
mkfs.fat -F 32 -n "boot" /dev/sda1

#格式化第一个系统分区,设置label
mkfs.ext4 -L rootfs1 /dev/sda2

#格式化第二个系统分区,设置label
mkfs.ext4 -L rootfs2 /dev/sda3

挂载boot分区

mount /dev/sda1 boot/

#创建两个系统的boot目录
mkdir boot/{os1,os2}

0x02.安装OS1

OS1安装官方系统

#挂载OS1的分区
mount /dev/sda2 root/

#挂载系统镜像
losetup -f --show 2020-08-20-raspios-buster-armhf.img

20201029112415.png

我这里是/dev/loop0,你的结果可能跟我不一样,在下面的命令中请将这个值替换为自己的结果。

#挂载镜像文件两个分区设备
kpartx -va /dev/loop0

mount /dev/mapper/loop0p2 osimg/
mount /dev/mapper/loop0p1 osimg/boot/

#拷贝OS1的boot目录
cp -a osimg/boot/* boot/os1/

umount osimg/boot/

#同步rootfs
rsync -axv osimg/ root/

mkdir root/bootpar

sed -i "s/\(PARTUUID=\)[[:xdigit:]-]\+\([[:blank:]]*\)\/boot/\1$(blkid -o value -s PARTUUID /dev/sda1)\2\/bootpar/" root/etc/fstab

sed -i "s/\(PARTUUID=\)[[:xdigit:]-]\+\([[:blank:]]*\/[[:blank:]]\+\)/\1$(blkid -o value -s PARTUUID /dev/sda2)\2/" root/etc/fstab

echo -e "/bootpar/os1 /boot  none bind 0 0\n" >> root/etc/fstab

sed -i "s/\(PARTUUID=\)[[:xdigit:]-]\+/\1$(blkid -o value -s PARTUUID /dev/sda2)/" boot/os1/cmdline.txt

#禁止自动扩容
sed -i 's/init=\/usr\/lib\/raspi-config\/init_resize.sh//' boot/os1/cmdline.txt

sync && sync

umount root/

umount osimg/

kpartx -d /dev/loop0

losetup -d /dev/loop0

0x03.安装OS2

OS2安装基地2.0

#挂载OS2的分区
mount /dev/sda3 root/

#挂载系统镜像
losetup -f --show 2020-06-22-OPENFANS-Debian-Buster-Desktop-Aarch64-ext4-v2020-2.0-U4-Release.img

20201029130743.png

我这里是/dev/loop0,你的结果可能跟我不一样,在下面的命令中请将这个值替换为自己的结果。

#挂载镜像文件两个分区设备
kpartx -va /dev/loop0

mount /dev/mapper/loop0p2 osimg/
mount /dev/mapper/loop0p1 osimg/boot/

#拷贝OS2的boot目录
cp -a osimg/boot/* boot/os2/

umount osimg/boot/

#同步rootfs
rsync -axv osimg/ root/

mkdir root/bootpar

sed -i "s/\(PARTUUID=\)[[:xdigit:]-]\+\([[:blank:]]*\)\/boot/\1$(blkid -o value -s PARTUUID /dev/sda1)\2\/bootpar/" root/etc/fstab

sed -i "s/\(PARTUUID=\)[[:xdigit:]-]\+\([[:blank:]]*\/[[:blank:]]\+\)/\1$(blkid -o value -s PARTUUID /dev/sda3)\2/" root/etc/fstab

echo -e "/bootpar/os2 /boot  none bind 0 0\n" >> root/etc/fstab

sed -i "s/\(PARTUUID=\)[[:xdigit:]-]\+/\1$(blkid -o value -s PARTUUID /dev/sda3)/" boot/os2/cmdline.txt

sync && sync

umount root/

umount osimg/

kpartx -d /dev/loop0

losetup -d /dev/loop0

0x04.处理boot

cp boot/os1/fixup* boot/
cp boot/os1/start* boot/
cp boot/os1/config.txt boot/

编辑boot/config.txt,在文件最前面加入以下内容:

[gpio2=1]
os_prefix=os1/
hdmi_force_hotplug=1
hdmi_group=2
hdmi_mode=85

[gpio2=0]
os_prefix=os2/
#配置基地2.0需要的参数
arm_64bit=1
arm_control=0x200
kernel=kernel8.img
disable_splash=1
dtparam=random=on
hdmi_force_hotplug=1
initramfs initrd.img
disable_overscan=1
dtparam=audio=on

对于不同系统上面的配置会有些许不同,大家灵活处理。

0x05.收尾

sync && sync

umount boot/

现在树莓派的双系统安装完成。

  1. 不短接任何引脚默认启动os1。
  2. 用母-母杜邦线短接3.3v和gpio2后再上电启动os1。
  3. 用母-母杜邦线短接GND和gpio2后再上电启动os2。

20201029154112.png

动手能力强的小伙伴可以做个开关控制不同系统启动 ^_^

如果觉得短接引脚麻烦,也可以用替换文件的方法切换系统:

  1. 用boot/os1/config.txt覆盖boot/config.txt,启动os1
  2. 用boot/os2/config.txt覆盖boot/config.txt,启动os2

替换文件的方法可以在win下操作,也可以在linux下操作。

测试

os1:
插上制作好的SD卡,用杜邦线短接3.3V和gpio2:
20201029155157.png
20201029155522.png

os2:
用杜邦线短接GND和gpio2:
20201029155218.png
20201029155942.png

双系统安装到不同设备也是可以实现的,原理都是一样的。

以上就是树莓派双系统的教程,很多地方都是很灵活的,方法不止一种,遇到问题要善于思考,实在思考不明白可以找我一起讨论。

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
4 https://linuxer.top/archives/raspi-dual-boot.html#comments https://linuxer.top/feed/
树莓派配置Oracle JDK8 https://linuxer.top/archives/raspi-jdk8.html https://linuxer.top/archives/raspi-jdk8.html Thu, 23 Jul 2020 19:10:00 +0800 kevin Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。今天讲一下树莓派如何配置Oracle JDK8。

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

jdk8下载地址:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

下载需要登录,也可以直接使用我下载的8u261

#切换到root用户
sudo -i

#根据自己系统选择arm32或者arm64
#arm32
wget https://linuxer.top/usr/uploads/2020/07/jdk-8u261-linux-arm32-vfp-hflt.tar.gz
tar -zxvf jdk-8u261-linux-arm32-vfp-hflt.tar.gz -C /usr/local/

#arm64
wget https://linuxer.top/usr/uploads/2020/07/jdk-8u261-linux-arm64-vfp-hflt.tar.gz
tar -zxvf jdk-8u261-linux-arm64-vfp-hflt.tar.gz -C /usr/local/

#创建软连接,方便升级
ln -sf /usr/local/jdk1.8.0_261/ /usr/local/jdk1.8

增加环境变量,编辑文件/etc/profile,在最后增加以下内容并保存:

export JAVA_HOME=/usr/local/jdk1.8
export PATH=$JAVA_HOME/bin:$PATH

使环境变量生效:

source /etc/profile

检查版本:

java -version

20200723202404.png

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
0 https://linuxer.top/archives/raspi-jdk8.html#comments https://linuxer.top/feed/
使用Gitea搭建代码托管平台 https://linuxer.top/archives/deploy-gitea.html https://linuxer.top/archives/deploy-gitea.html Wed, 24 Jun 2020 19:47:00 +0800 kevin 搞开发的同学都应该知道git,可以说git是目前最先进的分布式版本控制系统,没有之一。git的诞生也有着传奇色彩,最初Linux内核的版本控制使用的是闭源的商业软件BitKeeper,后来因为一些事情Linux团队跟他们闹翻了,Linus Torvalds决定开发自己的版本管理系统不再受制于人,10天后git诞生了,没错是10天!

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

git的优点不再赘述,主要讲一下如何在树莓派上用Gitea部署自己的git代码托管平台。

如果是大、中型团队推荐使用GitLab,如果是中、小型团队或者个人使用,那么Gitea非常适合你。

Gitea是一个开源社区驱动的Gogs克隆,是一个轻量级的代码托管解决方案,后端采用Go编写,采用MIT许可证。可运行在WindowsmacOSLinuxARM等平台。相比Gogs来说更新频率更高,推荐使用。

推荐使用基地2.0系统进行部署。

首先参考https://linuxer.top/archives/raspi-install-mysql57.html这篇文章安装Mysql数据库或者MariaDB,当然也可以不安装,Gitea也支持使用SQLite,推荐使用MysqlMariaDB

Mysql创建数据库gitea编码使用utf8mb4,创建用户gitea,把数据库gitea的权限赋给用户gitea

配置环境:

#更新系统
sudo apt update
sudo apt upgrade

#安装git
#如果想用最新版git可以参考git官网编译安装
sudo apt install git

#创建git用户
sudo useradd -m -s /bin//bash git

#切换到git
su - git

#创建工作目录
mkdir gitea

cd gitea

#到https://github.com/go-gitea/gitea/releases
#找最新的arm64发布版本地址
#目前是1.12.1
#下载
wget https://github.com/go-gitea/gitea/releases/download/v1.12.1/gitea-1.12.1-linux-arm64.xz

#解压
xz -d gitea-1.12.1-linux-arm64.xz

#赋执行权限
chmod u+x gitea-1.12.1-linux-arm64

#创建软连接,方便更新
ln -sf gitea-1.12.1-linux-arm64 gitea

#如果需要更新版本的时候,先停掉服务
#下载最新的可执行文件解压
#创建软连接到最新版
#ln -sf gitea-x.xx.x-linux-arm64 gitea
#然后启动服务

#启动服务
#sudo systemctl start gitea.service

#停止服务
#sudo systemctl stop gitea.service

创建systemd服务
开一个新终端窗口,用root权限创建文件/etc/systemd/system/gitea.service,内容如下:

[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target

#根据使用的数据库打开下面的注释
#我这里用的mysql
Requires=mysql.service
#Requires=mariadb.service

[Service]
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/home/git/gitea/
ExecStart=/home/git/gitea/gitea web
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/home/git/gitea

[Install]
WantedBy=multi-user.target

使用root权限启动服务:

#刷新服务
systemctl daemon-reload

#设置开机启动
systemctl enable gitea.service

#启动
systemctl start gitea.service

这时服务已经启动,访问ip:3000/install进行安装配置,我这里的地址是192.168.1.240:3000/install

数据库配置:
20200624194200.png

一般配置,这里的各种路径根据自己需求进行填写,不明白什么意思的就保持默认:
20200624194453.png

可选设置中配置管理员账户,注意,这里不能用admin作为用户名:
20200624201501.png

没有提到的配置大家根据自己需求设置,然后开始安装,安装完成后跳转到首页:
20200624201825.png

部署完成,更多的功能大家自己探索吧~

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
3 https://linuxer.top/archives/deploy-gitea.html#comments https://linuxer.top/feed/
树莓派替换开机树莓logo https://linuxer.top/archives/replace-raspi-logo.html https://linuxer.top/archives/replace-raspi-logo.html Mon, 22 Jun 2020 19:09:00 +0800 kevin 树莓派启动时会根据核心数量显示不同数量的树莓logo,今天讲一下如何替换这个树莓logo。

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

这个logo是在内核中的,不能通过替换资源文件的方式更换,只能在内核源码中替换,然后编译内核才能生效。

首先clone内核源码:

git clone --depth=1 https://github.com/raspberrypi/linux

默认图片的位置在drivers/video/logo/logo_linux_clut224.ppm

ppm也是一种图片格式,大家可以百度一下,这个ppm转为png后就是下图:
raspi_logo.png

分辨率为63x80,我们先制作一个相同分辨率的pnglogo.png

然后安装netpbm

apt update 
apt install netpbm

然后开始转换:

pngtopnm logo.png | ppmquant -fs 224 | pnmtoplainpnm > logo_linux_clut224.ppm

logo_linux_clut224.ppm覆盖内核原文件,然后编译安装内核。

内核编译安装步骤参考https://linuxer.top/archives/build-raspi-osimg.html

最后上个效果图:
20200622191806.png

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
0 https://linuxer.top/archives/replace-raspi-logo.html#comments https://linuxer.top/feed/
从零开始构建树莓派64位系统 https://linuxer.top/archives/build-raspi-osimg.html https://linuxer.top/archives/build-raspi-osimg.html Fri, 19 Jun 2020 14:10:00 +0800 kevin 树莓派从3B开始就是64位cpu,但是官方系统一直都是32位的,直到2020-05-28才发布64位beta版,在此之前我除了使用基地的64位系统之外也自己构建过,这篇文章将详细讲一下如何从零开始构建自己的树莓派64位系统。

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

树莓派官方系统是基于Debian的,所以我们也选择Debian Buster进行构建。整个构建过程可以在安装Linux系统的PC或服务器上进行,也可以在64位树莓派上进行(推荐使用基地2.0最新的u3),我使用x64平台的Ubuntu 20.04进行演示,过程中我会说明与使用树莓派不同的地方,没有说明的就是通用的。

一、准备镜像

我们首先来创建镜像文件,这次我们构建的是lite系统不包含桌面环境,所以我创建一个3G的镜像(其实2G就够),这里可以根据自己定制的需要改变镜像的大小。

为了避免频繁使用sudo,全程使用root用户操作。

#切换到root
sudo -i

#更新系统软件
apt update
apt upgrade

#安装所需要的软件
apt install kpartx

#创建一个工作目录,所有工作都在此目录进行
mkdir debian

cd debian

#创建镜像文件buster.img
dd if=/dev/zero of=buster.img bs=3G count=0 seek=1

#给镜像文件分区
cfdisk buster.img

树莓派系统镜像有两个分区,一个boot分区类型为FAT32,一个rootfs根分区类型为ext4,下面开始分区

进入cfdisk交互模式后,选择dos类型:
20200621143029.png

然后用左右键选择新建,输入分区大小256M,类型选择主分区
20200621143115.png
20200621143156.png
20200621143236.png

然后用上下键选择刚刚创建的256M分区,左右键选择类型,弹出对话框选择类型c
20200621143722.png
20200621143756.png

然后在剩余空间上选择新建,分区大小默认,类型选择主分区
20200621143825.png

然后有左右按键选写入,提示输入yes
20200621143915.png
20200621143943.png

然后按q键或者选择退出

镜像分区完成,现在开始格式化镜像:

#挂载镜像文件
losetup -f --show buster.img

执行完上面的挂载命令会得到一个输出,表示挂载的loop设备:
20200621142417.png

我这里是/dev/loop10,你的结果可能跟我不一样,在下面的命令中请将这个值替换为自己的结果。

#挂载镜像文件两个分区设备
kpartx -va /dev/loop10

执行完上面的命令会把两个分区设备映射到/dev/mapper/下,具体设备名称看自己的输出:
20200621153526.png

我的结果表明,镜像第一个分区设备为/dev/mapper/loop10p1,第二个分区设备为/dev/mapper/loop10p2

格式化两个分区,注意替换自己的设备名称

#格式化boot分区
mkfs.fat -F 32 -n "boot" /dev/mapper/loop10p1

#格式化rootfs,设置label
mkfs.ext4 -L rootfs /dev/mapper/loop10p2

创建两个挂载点并挂载两个分区:

mkdir boot rootfs

#挂载boot
mount /dev/mapper/loop10p1 boot/

#挂载rootfs
mount /dev/mapper/loop10p2 rootfs/

执行lsblk确认一下挂载情况:
20200621155717.png

镜像准备完毕。

二、rootfs构建

现在开始rootfs的构建

#安装所需要的软件
#x64平台
apt install debootstrap qemu-user-static

#树莓派
apt install debootstrap

#使用debootstrap构建基础系统
#--arch=arm64指定目标架构
#buster表示要构建的发行版
#rootfs/表示构建目录
#https://mirrors.tuna.tsinghua.edu.cn/debian/ 表示使用的源

#x64执行
#--foreign表示异构系统构建
debootstrap --arch=arm64 --no-merged-usr --foreign buster rootfs/ https://mirrors.tuna.tsinghua.edu.cn/debian/

#树莓派执行
debootstrap --arch=arm64 --no-merged-usr buster rootfs/ https://mirrors.tuna.tsinghua.edu.cn/debian/

#下载驱动
wget https://linuxer.top/usr/uploads/2020/06/firmware.tar.xz

#解压驱动
tar -Jxvf firmware.tar.xz -C rootfs/lib/

#下载固件
wget -O rpi-firmware.tar.gz https://github.com/Hexxeh/rpi-firmware/tarball/master
mkdir rpi-firmware
tar -zxvf rpi-firmware.tar.gz -C rpi-firmware --strip-components 1
cp -r rpi-firmware/vc/hardfp/opt/vc rootfs/opt/
cp -r rpi-firmware/vc/sdk/opt/vc rootfs/opt/

执行blkid /dev/mapper/loop10*,根据结果编辑rootfs/etc/fstab文件:
20200621175449.png

我的rootfs/etc/fstab文件内容如下,大家根据实际情况修改:

proc            /proc           proc    defaults          0       0
PARTUUID=ec5f336e-01  /boot           vfat    defaults          0       2
PARTUUID=ec5f336e-02  /               ext4    defaults,noatime  0       1

改为清华源,编辑rootfs/etc/apt/sources.list,修改为以下内容:

deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main non-free contrib
deb http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main non-free contrib
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main non-free contrib

扩容脚本,创建rootfs/usr/sbin/init_resize.sh,写入以下内容:

#!/bin/sh

reboot_pi () {
  umount /boot
  mount / -o remount,ro
  sync
  if [ "$NOOBS" = "1" ]; then
    if [ "$NEW_KERNEL" = "1" ]; then
      reboot -f "$BOOT_PART_NUM"
    else
      echo "$BOOT_PART_NUM" > "/sys/module/${BCM_MODULE}/parameters/reboot_part"
    fi
  fi
  echo b > /proc/sysrq-trigger
  sleep 5
  exit 0
}

check_commands () {
  if ! command -v whiptail > /dev/null; then
      echo "whiptail not found"
      sleep 5
      return 1
  fi
  for COMMAND in grep cut sed parted fdisk findmnt; do
    if ! command -v $COMMAND > /dev/null; then
      FAIL_REASON="$COMMAND not found"
      return 1
    fi
  done
  return 0
}

check_noobs () {
  if [ "$BOOT_PART_NUM" = "1" ]; then
    NOOBS=0
  else
    NOOBS=1
  fi
}

get_variables () {
  ROOT_PART_DEV=$(findmnt / -o source -n)
  ROOT_PART_NAME=$(echo "$ROOT_PART_DEV" | cut -d "/" -f 3)
  ROOT_DEV_NAME=$(echo /sys/block/*/"${ROOT_PART_NAME}" | cut -d "/" -f 4)
  ROOT_DEV="/dev/${ROOT_DEV_NAME}"
  ROOT_PART_NUM=$(cat "/sys/block/${ROOT_DEV_NAME}/${ROOT_PART_NAME}/partition")

  BOOT_PART_DEV=$(findmnt /boot -o source -n)
  BOOT_PART_NAME=$(echo "$BOOT_PART_DEV" | cut -d "/" -f 3)
  BOOT_DEV_NAME=$(echo /sys/block/*/"${BOOT_PART_NAME}" | cut -d "/" -f 4)
  BOOT_PART_NUM=$(cat "/sys/block/${BOOT_DEV_NAME}/${BOOT_PART_NAME}/partition")

  OLD_DISKID=$(fdisk -l "$ROOT_DEV" | sed -n 's/Disk identifier: 0x\([^ ]*\)/\1/p')

  check_noobs

  ROOT_DEV_SIZE=$(cat "/sys/block/${ROOT_DEV_NAME}/size")
  TARGET_END=$((ROOT_DEV_SIZE - 1))

  PARTITION_TABLE=$(parted -m "$ROOT_DEV" unit s print | tr -d 's')

  LAST_PART_NUM=$(echo "$PARTITION_TABLE" | tail -n 1 | cut -d ":" -f 1)

  ROOT_PART_LINE=$(echo "$PARTITION_TABLE" | grep -e "^${ROOT_PART_NUM}:")
  ROOT_PART_START=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 2)
  ROOT_PART_END=$(echo "$ROOT_PART_LINE" | cut -d ":" -f 3)

  if [ "$NOOBS" = "1" ]; then
    EXT_PART_LINE=$(echo "$PARTITION_TABLE" | grep ":::;" | head -n 1)
    EXT_PART_NUM=$(echo "$EXT_PART_LINE" | cut -d ":" -f 1)
    EXT_PART_START=$(echo "$EXT_PART_LINE" | cut -d ":" -f 2)
    EXT_PART_END=$(echo "$EXT_PART_LINE" | cut -d ":" -f 3)
  fi
}

fix_partuuid() {
  mount -o remount,rw "$ROOT_PART_DEV"
  mount -o remount,rw "$BOOT_PART_DEV"
  DISKID="$(tr -dc 'a-f0-9' < /dev/hwrng | dd bs=1 count=8 2>/dev/null)"
  fdisk "$ROOT_DEV" > /dev/null <<EOF
x
i
0x$DISKID
r
w
EOF
  if [ "$?" -eq 0 ]; then
    sed -i "s/${OLD_DISKID}/${DISKID}/g" /etc/fstab
    sed -i "s/${OLD_DISKID}/${DISKID}/" /boot/cmdline.txt
    sync
  fi

  mount -o remount,ro "$ROOT_PART_DEV"
  mount -o remount,ro "$BOOT_PART_DEV"
}

check_variables () {
  if [ "$NOOBS" = "1" ]; then
    if [ "$EXT_PART_NUM" -gt 4 ] || \
       [ "$EXT_PART_START" -gt "$ROOT_PART_START" ] || \
       [ "$EXT_PART_END" -lt "$ROOT_PART_END" ]; then
      FAIL_REASON="Unsupported extended partition"
      return 1
    fi
  fi

  if [ "$BOOT_DEV_NAME" != "$ROOT_DEV_NAME" ]; then
      FAIL_REASON="Boot and root partitions are on different devices"
      return 1
  fi

  if [ "$ROOT_PART_NUM" -ne "$LAST_PART_NUM" ]; then
    FAIL_REASON="Root partition should be last partition"
    return 1
  fi

  if [ "$ROOT_PART_END" -gt "$TARGET_END" ]; then
    FAIL_REASON="Root partition runs past the end of device"
    return 1
  fi

  if [ ! -b "$ROOT_DEV" ] || [ ! -b "$ROOT_PART_DEV" ] || [ ! -b "$BOOT_PART_DEV" ] ; then
    FAIL_REASON="Could not determine partitions"
    return 1
  fi
}

check_kernel () {
  MAJOR="$(uname -r | cut -f1 -d.)"
  MINOR="$(uname -r | cut -f2 -d.)"
  if [ "$MAJOR" -eq "4" ] && [ "$MINOR" -lt "9" ]; then
    return 0
  fi
  if [ "$MAJOR" -lt "4" ]; then
    return 0
  fi
  NEW_KERNEL=1
}

main () {
  get_variables

  if ! check_variables; then
    return 1
  fi

  check_kernel

  if [ "$NOOBS" = "1" ] && [ "$NEW_KERNEL" != "1" ]; then
    BCM_MODULE=$(grep -e "^Hardware" /proc/cpuinfo | cut -d ":" -f 2 | tr -d " " | tr '[:upper:]' '[:lower:]')
    if ! modprobe "$BCM_MODULE"; then
      FAIL_REASON="Couldn't load BCM module $BCM_MODULE"
      return 1
    fi
  fi

  if [ "$ROOT_PART_END" -eq "$TARGET_END" ]; then
    reboot_pi
  fi

  if [ "$NOOBS" = "1" ]; then
    if ! parted -m "$ROOT_DEV" u s resizepart "$EXT_PART_NUM" yes "$TARGET_END"; then
      FAIL_REASON="Extended partition resize failed"
      return 1
    fi
  fi

  if ! parted -m "$ROOT_DEV" u s resizepart "$ROOT_PART_NUM" "$TARGET_END"; then
    FAIL_REASON="Root partition resize failed"
    return 1
  fi

  fix_partuuid

  return 0
}

mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t tmpfs tmp /run
mkdir -p /run/systemd

mount /boot
mount / -o remount,ro

sed -i 's| init=/usr/sbin/init_resize\.sh||' /boot/cmdline.txt
sed -i 's| sdhci\.debug_quirks2=4||' /boot/cmdline.txt

if ! grep -q splash /boot/cmdline.txt; then
  sed -i "s/ quiet//g" /boot/cmdline.txt
fi
mount /boot -o remount,ro
sync

echo 1 > /proc/sys/kernel/sysrq

if ! check_commands; then
  reboot_pi
fi

if main; then
  whiptail --infobox "Resized root filesystem. Rebooting in 5 seconds..." 20 60
  sleep 5
else
  sleep 5
  whiptail --msgbox "Could not expand filesystem, please try raspi-config or rc_gui.\n${FAIL_REASON}" 20 60
fi

reboot_pi

rootfs/usr/sbin/init_resize.sh赋执行权限:

chmod +x rootfs/usr/sbin/init_resize.sh

第一次开机执行resize2fs扩容,创建rootfs/etc/init.d/resize2fs_once,写入以下内容:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          resize2fs_once
# Required-Start:
# Required-Stop:
# Default-Start: 3
# Default-Stop:
# Short-Description: Resize the root filesystem to fill partition
# Description:
### END INIT INFO
. /lib/lsb/init-functions
case "$1" in
  start)
    log_daemon_msg "Starting resize2fs_once"
    ROOT_DEV=$(findmnt / -o source -n) &&
    resize2fs $ROOT_DEV &&
    update-rc.d resize2fs_once remove &&
    rm /etc/init.d/resize2fs_once &&
    log_end_msg $?
    ;;
  *)
    echo "Usage: $0 start" >&2
    exit 3
    ;;
esac

rootfs/etc/init.d/resize2fs_once赋执行权限:

chmod +x rootfs/etc/init.d/resize2fs_once

创建rootfs/etc/rc.local,写入以下内容,实现开机自动执行,这里根据自己需求定制:

#!/bin/sh -e
#
#/usr/sbin/gen-server-key
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#


exit 0

rootfs/etc/rc.local赋执行权限:

chmod +x rootfs/etc/rc.local

有了基础系统之后我们chroot进行系统配置,由于我使用的x64平台跟arm64属于异构系统,所以这里要使用qemu进行模拟

x64平台:

#x64平台进行第二阶段构建
chroot rootfs/ debootstrap/debootstrap --second-stage

cp /usr/bin/qemu-aarch64-static rootfs/usr/bin/

#chroot进入基础系统
chroot rootfs/ /usr/bin/qemu-aarch64-static /bin/bash

树莓派:

#chroot进入基础系统
chroot rootfs/ /bin/bash

到这里,我们已经chroot到rootfs目录中了,如果你出现了cannot change locale的错误,没关系,忽略就好了。
现在可以对基础系统进行配置了:

#添加32位软件支持
dpkg --add-architecture armhf

#更新系统软件
apt update
apt upgrade

#安装基础软件
apt install libc6:armhf
apt install locales rng-tools wpasupplicant dhcpcd5 sudo parted
apt install net-tools avahi-daemon dphys-swapfile ssh openssh-server 
apt install htop bash-completion wget curl vim

#添加vc-userland支持
echo "/opt/vc/lib/"   >/etc/ld.so.conf.d/vc-userland.conf
cd /usr/bin/ ; for i in /opt/vc/bin/* ; do ln -sf $i ./ ; done ; cd /

#设置swap为1024M
#根据自己需求修改
sed -i "s/#CONF_SWAPSIZE=/CONF_SWAPSIZE=1024/g" /etc/dphys-swapfile

#设置扩容自动执行
update-rc.d resize2fs_once defaults

#设置内核参数
echo -e "kernel.printk = 3 4 1 3\nvm.min_free_kbytes = 16384" > /etc/sysctl.d/98-rpi.conf
echo -e "net.core.default_qdisc=fq\nnet.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf

#设置时区为上海
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

#添加wpa_supplicant启动钩子
ln -sf /usr/share/dhcpcd/hooks/10-wpa_supplicant /lib/dhcpcd/dhcpcd-hooks/10-wpa_supplicant

#链接wpa_supplicant配置文件到boot分区,这样可以开机前配置wifi
ln -sf /boot/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf

#设置主机名为raspberrypi
echo "raspberrypi" > /etc/hostname
echo -e "127.0.0.1\traspberrypi" >> /etc/hosts

#配置语言
dpkg-reconfigure locales

在弹出窗口用空格选则en_US.UTF-8zh_CN.UTF-8,然后tab键选择确定
20200621194722.png
20200621194746.png

然后选择默认语言,我这里选择en_US.UTF-8,然后tab键选择确定
20200621194806.png

添加用户:

#添加用pi
useradd -m -s /bin/bash pi

#设置密码,输入两次确认
passwd pi

#给pi添加sudo权限
echo "pi    ALL=(ALL:ALL)  NOPASSWD: ALL" > /etc/sudoers.d/00_pi

如果需要开启root用户ssh登录可以这样操作,不需要的可以忽略:

#修改root密码,输入两次确认
passwd

#开启root ssh登录
sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config

基本配置完成,下面配置一些定制内容,可以根据自己需求来,不需要的可以忽略:

#安装Git、python3
apt install git python3 python3-pip

#添加python3的gpio库
pip3 install RPi.GPIO

镜像定制的需求在这里自由发挥,发挥完以后退出chroot环境:

sync

exit

#清除日志
echo > rootfs/root/.bash_history

sync

三、boot分区文件准备

现在开始准备boot分区的文件:

#拷贝BootLoader
cp rpi-firmware/bootcode.bin rpi-firmware/fixup* rpi-firmware/start* boot/

执行blkid /dev/mapper/loop10p2,其中loop10p2替换为自己的设备名称,根据结果替换下面root=PARTUUID=的值。

创建boot/cmdline.txt,内容如下:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=ec5f336e-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait init=/usr/sbin/init_resize.sh

创建boot/config.txt,内容如下:

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

arm_64bit=1

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
#dtoverlay=vc4-fkms-v3d

创建boot/wpa_supplicant.conf,实现开机前配置wifi,内容如下:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=CN

network={
    ssid="wifi名称"
    psk="wifi密码"
    key_mgmt=WPA-PSK
    priority=1
}

如果不需要配置wifi,在上面文件每一行前面加一个#注释掉即可。

四、内核构建

树莓派开机logo也是在内核中修改,需要的可以参考下文
https://linuxer.top/archives/replace-raspi-logo.html

现在开始内核编译,首先clone官方内核代码到本地:

#安装git
apt install git

#clone代码
#我们clone默认分支,版本是4.19.y
#需要其他分支 添加 -b 分支名称
git clone --depth=1 https://github.com/raspberrypi/linux

修改EXTRAVERSION实现自定义内核版本号,修改linux/Makefile文件第5行:

EXTRAVERSION = -kevin

这样内核的版本显示为4.19.y-kevin,这里根据自己需求修改。

开始编译,如果使用x64请参考1、交叉编译,使用树莓派编译请参考2、树莓派编译

1、交叉编译

#配置交叉编译环境
apt install build-essential gcc-aarch64-linux-gnu bc bison flex libssl-dev make libc6-dev libncurses5-dev

#进入源码目录
cd linux

#配置内核
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig

#如果想对内核做一些配置可以执行此命令
#在弹出框里可以配置内核各种参数
#这里不做展开,相关资料自行查阅
#保持默认参数可以跳过此命令
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

#开始编译
#这里会花费一定的时间,具体看你电脑配置
#-j4 后面的4可以改成cpu核心数加快编译
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j4


#安装内核模块
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=../rootfs modules_install

#拷贝内核到boot分区
cp arch/arm64/boot/Image ../boot/kernel8.img

#拷贝dtb到boot分区
cp arch/arm64/boot/dts/broadcom/*.dtb ../boot/

#拷贝overlays到boot分区
cp -r arch/arm64/boot/dts/overlays/ ../boot/

2、树莓派编译

使用树莓派编译时cpu几乎会满载,如果你有其他服务正在运行,建议先停掉。

配置编译环境:

apt install tmux build-essential bc bison flex libssl-dev make libc6-dev libncurses5-dev

如果你树莓派是ssh登录的,我强烈建议你使用tmux或者screen创建新会话来编译,我这里选择tmux:

#进入源码目录
cd linux

#创建新会话kernel
tmux new -s kernel

#配置内核
make ARCH=arm64 bcm2711_defconfig

#如果想对内核做一些配置可以执行此命令
#在弹出框里可以配置内核各种参数
#这里不做展开,相关资料自行查阅
#保持默认参数可以跳过此命令
make ARCH=arm64 menuconfig

#开始编译
#这里会花费很长时间,可以出去休息一会
#我用4b4g大约90分钟左右
make ARCH=arm64 -j4

#退出tmux
exit

#安装内核模块
make ARCH=arm64 INSTALL_MOD_PATH=../rootfs modules_install

#拷贝内核到boot分区
cp arch/arm64/boot/Image ../boot/kernel8.img

#拷贝dtb到boot分区
cp arch/arm64/boot/dts/broadcom/*.dtb ../boot/

#拷贝overlays到boot分区
cp -r arch/arm64/boot/dts/overlays/ ../boot/

#如果ssh连接断开可以重新连接切换到root执行以下命令重连
#编译过程不会中止
#没断开自然更好,可以忽略此命令
tmux attach -t kernel

至此内核编译完成。

五、收尾

最后做一些收尾工作:

cd ../

sync

#卸载镜像分区挂载
umount boot/
umount rootfs/

#注意/dev/loop10改为自己的挂载设备
kpartx -d /dev/loop10
losetup -d /dev/loop10

到这里我们的镜像就算做好了,兼容3B3B+4B,现在把buster.img刷到卡上验证一下。

20200622175742.png
20200622175852.png
20200622180058.png
20200622181338.png

2020年初就想总结一下,一拖拖了半年了,终于写完了,一身轻松~~

都是野路子让大佬们见笑了~

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
2 https://linuxer.top/archives/build-raspi-osimg.html#comments https://linuxer.top/feed/
树莓派安装mysql5.7 https://linuxer.top/archives/raspi-install-mysql57.html https://linuxer.top/archives/raspi-install-mysql57.html Fri, 05 Jun 2020 16:51:00 +0800 kevin MySQL是一款非常优秀的关系型数据库,因为其速度、可靠性和适应性而备受关注,很多大型网站都是用Mysql作为数据存储,今天讲一下如何在树莓派上安装mysql5.7。

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

正式开始之前先要说一下MySQLMariaDB的关系。随着Oracle收购Sun公司,MySQL也归到了Oracle的名下,MySQL之父的Michael在意识到MySQL有闭源风险之后,新开了一个分支,作了部分修改,形成了MariaDB。互联网用户以及Linux发行商纷纷抛弃MySQL,转投MariaDB阵营,Debian从9开始也用MariaDB替换了MySQL,所以我们现在不能直接在apt的源中安装MySQLMariaDB初期和MySQL可以说是在代码级兼容的,但是随着各自分支的发展和新特性的加入,不兼容的地方会越来越多,我强烈建议在项目一开始就选择好数据库,否则后期迁移数据也是个头疼的事。

如果选择MariaDB,执行apt update && apt install mariadb-server,搞定,后面可以忽略了,教程结束。

选择MySQL请继续阅读

先做准备工作:

#切换到root用户
sudo -i

#升级系统
apt update
apt upgrade

如果你是32系统,例如官方32系统:

wget https://linuxer.top/usr/uploads/2020/06/mysql57_armhf.tar.gz

#解压
tar -zxvf mysql57_armhf.tar.gz

cd mysql57_armhf/

apt install ./*.deb

#安装完成,检查mysql版本
mysql -V

如果你是64位系统,例如基地2.0、官方64位系统或其他64位自制Debian:

wget https://linuxer.top/usr/uploads/2020/06/mysql57_arm64.tar.gz

#解压
tar -zxvf mysql57_arm64.tar.gz

cd mysql57_arm64/

apt install ./*.deb

#安装完成,检查mysql版本
mysql -V

root密码默认为空,可以执行mysql_secure_installation进行初始化配置。

这是基地2.0系统的安装效果
20200605191626.png

MySQL的各种配置这里不讲了,需要改的东西大家自己百度就ok,资料很多的。

如果是想配置lnmp环境又不想自己折腾,可以从这里下载配置好宝塔镜像,刷到卡里就能用,非常方便。

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
4 https://linuxer.top/archives/raspi-install-mysql57.html#comments https://linuxer.top/feed/
宝塔7.4.5树莓派镜像 https://linuxer.top/archives/bt-raspi-img.html https://linuxer.top/archives/bt-raspi-img.html Wed, 03 Jun 2020 01:49:00 +0800 kevin 宝塔面板是一款使用方便、功能强大且终身免费的服务器管理软件,支持Linux与Windows系统。一键配置:LAMP/LNMP、网站、数据库、FTP、SSL,通过Web端轻松管理服务器。该面板可以运行在树莓派上,但是由于软件都是编译安装,耗时长且容易出错,为了方便大家使用,我制作了一个配置好宝塔环境的镜像,有需要的朋友可以下载使用。

镜像说明

这个镜像是基于Debian10(buster)arm64系统,内核版本为4.19.97,宝塔版本为7.2.0,(2020-09-05日更新版升级内核为5.4.51,升级宝塔版本为7.4.5),已更换清华源,已更新最新BootLoad,可以刷到USB设备启动,USB启动设置请参考这里或者这里,如果需要迁移到移动硬盘请参考这里

兼容3B3B+4B

此镜像无桌面环境,默认开启ssh服务,支持开机前配置wifi,方法为修改boot分区wpa_supplicant.conf文件。

根据需要配置一个或多个wifi连接信息,去掉network块前的#,将ssidpassword替换为真实值即可。

示例:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=CN

network={
    ssid="无线ssid"
    psk="无线密码"
    key_mgmt=WPA-PSK
    priority=1
}

默认用户/密码:pi/raspberryroot用户没有启用,如果需要请自行开启。

如果刷入到SD卡或U盘中,需要手动扩容,方法为:

sudo resize.root

7.4.5版本自动扩容,无需手动操作!

默认swap大小为200M,如需修改,请编辑/etc/dphys-swapfile文件,修改CONF_SWAPSIZE=200,单位为MB,如果需要设置1G,则配置为CONF_SWAPSIZE=1024,保存文件执行sudo systemctl restart dphys-swapfile.service重启服务即可。

面板为纯净面板,安装软件如下:

20200603015531.png

面板操作方法:

sudo bt

20200603015828.png

根据需要选择功能并输入对应编号即可,上图输入14为获取面板信息,这里可以获取面板默认安全入口和默认用户名密码,登录之后请立即修改密码和安全入口地址!!

我部署了一个typecho测试,功能正常

20200603020513.png

20200603020606.png

20200603020655.png

20200603020846.png

20200603021040.png

这里提供两个版本的下载,python2python3,宝塔官方说py3版本可能存在少量兼容问题,但是实际使用过程中没有发现明显区别,建议选择py3版本,毕竟py2已经寿终正寝了。

2020-09-05更新

  1. 内核升级到5.4.51
  2. 宝塔版本升级到7.4.5
  3. 增加自动扩容功能,第一次启动自动扩容,无需手动操作

下载地址

下载地址:https://pan.baidu.com/s/1kQfw4hTUjOVaDtcHf4ekdQ ,提取码:ltiu

文件说明:

  1. bt-7.2.0-py2-buster-aarch64.img.xz,宝塔7.2.0,内核4.19.97,python2
  2. bt-7.2.0-py3-buster-aarch64.img.xz,宝塔7.2.0,内核4.19.97,python3
  3. bt-7.4.5-py3-buster-aarch64.img.xz,宝塔7.4.5,内核5.4.51,python3,强烈推荐
本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
5 https://linuxer.top/archives/bt-raspi-img.html#comments https://linuxer.top/feed/
树莓派系统迁移到移动硬盘 https://linuxer.top/archives/raspi-usb-disk-boot.html https://linuxer.top/archives/raspi-usb-disk-boot.html Mon, 01 Jun 2020 12:27:00 +0800 kevin 之前的文章介绍了4B设置USB启动的方法和系统迁移到USB设备的方法,主要思路就是生成当前系统的最小备份镜像然后将镜像刷入USB设备,这样做对于U盘这样的设备还是很好的,但是对于大容量的移动硬盘是不适用的,镜像刷入硬盘后,之前的分区和数据都会被覆盖。这篇文章就讲一下如何在保留硬盘数据的情况下迁移树莓派系统。

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

本教程兼容官方系统、基地2.0系统、Ubuntu。

这篇文章只讲系统迁移,USB启动设置请参考这里或者这里

想让树莓派正常启动至少需要两个分区,一个FAT32分区,一个ext4分区(f2fs、btrfs也可以,看自己需要),FAT32分区存放BootLoader内核配置文件等,ext4分区为roofs挂载为根节点。我们现在要调整硬盘,把这两个分区规划出来,FAT32分区大小256M足够了多了没用,ext4分区看自己需求,建议16g以上。使用工具为DiskGenius。

打开DiskGenius,可以看到我这块硬盘目前有三个分区:
20200601120707.png

我的规划是留三个150G分区,剩下的用来迁移系统,这里注意一下,FAT32分区最好是整个磁盘第一个分区,ext4分区无所谓,所以这里调整第一个分区,在前面划出一部分空间备用,在第一分区上点击右键,选择调整分区大小
20200601121537.png

在弹出对话框中改变分区大小,让分区前出现空闲空间:
20200601121751.png

执行完之后的分区如下:
20200601122254.png

在空闲分区处新建一个NTFS分区并设置为主分区,然后保存更改:
20200601141744.png

我要迁移的系统是无桌面的,所以15G是完全够用的。
现在磁盘的调整已经完成,下面的操作在树莓派上进行,把要迁移的SD卡插到树莓派上启动,然后将调整好的硬盘插到USB接口上。

后面的操作都需要root权限,执行sudo -i切换到root用户:

#切换到root
sudo -i

#查看磁盘情况
lsblk

20200601143115.png

可以看到我的硬盘设备为sda,下面对sda进行分区操作,创建FAT32和ext4分区:

#使用cfdisk操作硬盘
#操作时根据具体情况将/dev/sda替换为自己的设备
cfdisk /dev/sda

用上下方向键选择我们创建的15.8G的NTFS分区,用左右按键选择Delete操作,然后回车:

20200601143345.png

然后创建FAT32分区,用上下方向键选择调整出来的Free space,用左右按键选择New操作,然后回车:

20200601143541.png

输入分区大小:256M,回车,然后上下键选择刚创建的分区,左右键选择Type操作,回车,选择类型c,回车:

20200601143634.png
20200601143704.png
20200601143720.png

然后创建ext4分区,用上下方向键选择Free space,用左右按键选择New操作,回车,使用默认大小,回车:

20200601143831.png

然后用左右按键选择Write操作,弹出提示输入yes,回车后按q退出:
20200601143903.png
20200601143919.png

磁盘的准备工作已经完成了,现在开始迁移系统。

先执行lsblk查看我们新建的分区:
20200601144347.png

从输出我们可以看出两个分区分区别为sda1(FAT32)sda3(ext4),现在开始格式化分区:

#更新源
apt update

#安装需要的软件
apt install -y dosfstools rsync

#格式化FAT32分区
#根据实际情况替换/dev/sda1为自己的设备
mkfs.vfat -F 32 -n `dosfslabel /dev/mmcblk0p1 | tail -n 1` /dev/sda1

#格式化ext4分区
#根据实际情况替换/dev/sda3为自己的设备
mkfs.ext4 /dev/sda3
e2label /dev/sda3 `e2label /dev/mmcblk0p2 | tail -n 1`

现在迁移boot分区:

#挂载sda1到/mnt/
#根据实际情况替换/dev/sda1为自己的设备
mount /dev/sda1 /mnt/

#拷贝boot分区文件
cp -rf `findmnt -n /dev/mmcblk0p1 | awk '{print $1}'`/* /mnt/

拷贝完boot分区文件后,要替换cmdline.txt中的PARTUUID:
执行blkid,找到sda3的PARTUUID(根据自己情况确定PARTUUID)

20200601144841.png

编辑/mnt/cmdline.txt文件,将root=PARTUUID=xxx中的xxx替换自己的执行结果,我的修改结果为root=PARTUUID=a8bf0107-03如果是ubuntu系统,这步可以忽略

同步根分区:

cd

#同步磁盘
sync

#反挂载/mnt
umount /mnt

#挂载sda3到/mnt/
#根据实际情况替换/dev/sda3为自己的设备
mount /dev/sda3 /mnt/

具体的同步工作需要写一个脚本来操作,创建文件syncrootfs.sh,内容如下:

#!/bin/bash

boot_mnt=`findmnt -n /dev/mmcblk0p1 | awk '{print $1}'`

rsync --force -rltWDEgop --delete --stats --progress \
    --exclude ".gvfs" \
    --exclude "$boot_mnt" \
    --exclude "/dev" \
    --exclude "/media" \
    --exclude "/mnt" \
    --exclude "/proc" \
    --exclude "/run" \
    --exclude "/snap" \
    --exclude "/sys" \
    --exclude "/tmp" \
    --exclude "lost\+found" \
    / /mnt

if [ ! -d $boot_mnt ]; then
    mkdir $boot_mnt
fi

if [ -d /snap ]; then
    mkdir /mnt/snap
fi

for i in boot dev media mnt proc run sys boot; do
    if [ ! -d /mnt/$i ]; then
        mkdir /mnt/$i
    fi
done

if [ ! -d /mnt/tmp ]; then
    mkdir /mnt/tmp
    chmod a+w /mnt/tmp
fi

sync

执行文件bash syncrootfs.sh,脚本会花费一定的时间,具体时间看迁移系统的大小,执行成功后如下图:
20200601150619.png

替换fstab文件中的PARTUUID,编辑/mnt/etc/fstab文件,将/boot/对应的PARTUUID修改为sda1sda3对应的PARTUUID如果是ubuntu系统,这步可以忽略

执行blkid
20200601151148.png

我修改后的结果为:
20200601151427.png

把改变同步到磁盘中:

cd

#同步磁盘
sync

#反挂载/mnt
umount /mnt

把硬盘插到电脑上,替换最新BootLoader,地址:https://github.com/Hexxeh/rpi-firmware,下载zip包,解压后把里面的fixup*.datstar*.elf文件拷贝到硬盘256M的FAT32分区替换原文件。

取下树莓派的SD卡,插上移动硬盘,上电。

启动后查看磁盘信息lsblk:
20200601152235.png

如果希望数据盘自动挂载,自行修改/etc/fstab文件,这里不做说明。

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
0 https://linuxer.top/archives/raspi-usb-disk-boot.html#comments https://linuxer.top/feed/
基地2.0系统USB启动 https://linuxer.top/archives/pifan-2-0-usb-boot.html https://linuxer.top/archives/pifan-2-0-usb-boot.html Sun, 31 May 2020 16:56:00 +0800 kevin 上一篇文章介绍了官方系统设置USB启动的方法,这篇文章讲一下树莓派爱好者基地2.0系统设置USB启动的方法,使用镜像为无桌面增强版(2019-12-30-OPENFANS-Debian-Buster-Aarch64-ext4-v2019-2.0-U2-Release-plus++)。

其实主要区别就在更新eeprom这一步,后面USB启动介质的制作是没有区别的。如果你只有一张卡,或者不想再刷个官方系统,那么可以参考这篇文章。

数据无价,本教程的操作有一定的风险,开始前请备份重要数据!!!

基地2.0系统做的非常完善,已经添加了rpi-eeprom的支持,但是由于版本太老,并不能使用最新的固件,所有我们要借助官方的rpi-eeprom项目来获取最新固件。

整个过程都需要root权限,如果你是用pi用户登录的,先执行sudo -i切换到root用户。

#卸载旧版rpi-eeprom
apt remove rpi-eeprom rpi-eeprom-images

#clone最新版本到本地
git clone https://github.com/raspberrypi/rpi-eeprom  /usr/local/rpi-eeprom

#将eeprom版本设置为beta版
echo 'FIRMWARE_RELEASE_STATUS="beta"' > /etc/default/rpi-eeprom-update

执行完上述操作后,将/usr/local/rpi-eeprom/usr/local/rpi-eeprom/firmware加入到PATH中,操作如下,编辑文件/etc/profile,在文件最后添加如下内容:

export PATH=/usr/local/rpi-eeprom:/usr/local/rpi-eeprom/firmware:$PATH

保存文件后执行下列语句使PATH生效

source /etc/profile

现在可以升级eeprom了。
如果想用固件的默认配置直接执行rpi-eeprom-update -d -a,然后重启完成升级。
如果想修改eeprom的参数配置,请参考这里

如果官方发布了新的固件,更新固件的方法为:

#打开项目地址
cd /usr/local/rpi-eeprom

#拉最新代码
git pull

#升级固件
rpi-eeprom-update -d -a

eeprom升级完成,下面讲一下如何把SD卡里的系统迁移到USB设备。

执行sudo -i切换到root用户

制作SD卡最小镜像:

git clone https://github.com/nanhantianyi/rpi-backup

cd rpi-backup/

#根据实际情况选择镜像的保存位置(具体参考README.md文件)
#我这里备份到我的U盘中,挂载路径为/media
./back.sh /media/rpi-back.img

上面的命令会给当前系统做一个备份并生成一个镜像,名字为rpi-back.img,这会花费一定时间,具体时间取决于你系统的已用的空间,耐心等待一会。

备份成功后将rpi-back.img文件拷贝到电脑,用软件把镜像烧到U盘中,如果不想迁移SD卡数据,可以忽略备份这个步骤,直接将2.0系统镜像刷到U盘中,不管是刷备份镜像还是直接刷系统镜像,都要替换BootLoader,地址:https://github.com/Hexxeh/rpi-firmware,下载zip包,解压后把里面的fixup*.datstar*.elf文件拷贝到U盘覆盖原文件。

好了,现在取出SD卡,插上U盘,加电,USB启动成功。

如果是刷的备份镜像,还需要手动扩容一下

#切换到root
sudo -i

#扩容rootfs
resize.root

好了,USB启动成功!
20200531200414.png

本文为原创文章,版权归 Kevin's Blog 所有,转载请联系博主获得授权。
]]>
0 https://linuxer.top/archives/pifan-2-0-usb-boot.html#comments https://linuxer.top/feed/