龙芯久久派Plus折腾笔记

xeonds

2024-09-12 15:41:18

感谢尚宇学长送的开发板,希望龙芯以后发展越来越好<(=w=)>

这回折腾用到的主要有:

开箱

尊贵的总裁签名版(虽然看不太清)↑

接口丰富度没得说,两个RJ45,两个USB2.0,一个3.5mm音频接口,UART,ADC,JTAG和Type-C供电,还有个MicroSD卡插槽。

这规格,只要三位数出头的价格,它就是炸了我都夸它炸得好听。稳定性跟功耗也没得说,ABI2.0的龙架构让它能拥有开源社区的支持,基本所有开源软件都可以通过交叉编译在这个板子上使用,未来可期属于是。

上电

手头刚好没USB转串口,想到个幽默办法。掏出以前的51单片机开发板HC6800MS,给ST89C52RC薅下来,TX,RX,GND分别接到开发板的RXD0,TXD0,GND上:

然后给那个老板子插电脑上:

诶,这不就有了吗。

现在就能用screen从串口连接上开发板了:

sudo screen /dev/ttyUSB0 115200

效果如下:

板子上电之后会默认启动WiFi热点,配置文件如下:

#/etc/hostapd.conf
interface=wlan0  
driver=nl80211  
ssid=LoongsonWIFI  
hw_mode=g  
channel=6  
macaddr_acl=0  
auth_algs=1  
ignore_broadcast_ssid=0  
wpa=2  
wpa_passphrase=loongson123456  
wpa_key_mgmt=WPA-PSK  
wpa_pairwise=TKIP  
rsn_pairwise=CCMP

虽然可以连上WiFi,但是它的sshd进程好像是默认不开启的。

哦它没有openssh啊。

交叉编译

在x86设备上跨架构构建龙芯的Arch Linux软件包 - 星外之神的博客 | wszqkzqk Blog pacman/提示和技巧 - Arch Linux 中文维基 离线安装 - Arch Linux 中文维基 从现有 Linux 发行版安装 Arch Linux - Arch Linux 中文维基

参数,来自xdosc的佬@chi

CFLAGS='--with-arch=loongarch64 --with-tune=la464 --with-abi=lp64d --with-simd=none --disable-threads'

OpenSSH

准备目录./openssh并进入,下载源码:

wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.8p  
1.tar.gz
wget http://www.zlib.net/zlib-1.3.1.tar.gz
wget https://github.com/openssl/openssl/releases/download/openssl-3.3.  
2/openssl-3.3.2.tar.gz
for item in $(ls ./);do tar -zxvf $item; done

创建目录./openssh/install 创建脚本env.sh:

#!/bin/bash
export PATH="$PATH:/path/to/cross-tools/bin"

上面指向的是交叉编译工具链的路径,提前准备。

准备环境:source ~/env.sh

编译zlib:

cd zlib-1.3.1/
prefix=$HOME/2k300/openssh/zlib CC=loongarch64-unknown-linux-gnu-gcc AR=loongarch64-unknown-linux-gnu-ar ./configure
make
make install

编译openssl

cd openssl-3.3.2/
./Configure linux64-loongarch64 --cross-compile-prefix=loongarch64-unknown-linux-gnu- --prefix=$HOME/2k300/openssh/install/openssl shared no-asm
make
make install

编译openssh:

./configure --host=loongarch64-unknown-linux-gnu --prefix=$HOME/2k300/openssh/install/openssh --with-ssl-dir=$HOME/2k300/openssh/install/openssl --with-zlib=$HOME  
/2k300/openssh/install/zlib LDFLAGS="-static -pthread" --sysconfdir=/etc/ssh --disable-strip
make
make install-files

注意 此处使用~概率会导致编译异常,使用$HOME代替

这里因为没找到在哪指定strip工具的位置而禁用了strip,所以产物会稍微有丶大。

编译结束之后,产物可以在$HOME/2k300/openssh/install/openssh中找到。直接把文件传输到99pi对应的目录里即可。

传输方法可以使用tty串口传输,不过速度太慢:

# server-side
uuencode [filename-in-99pi] < [file] > /dev/ttyUSB0
# 99pi-side
uudecode < /dev/ttyS0 

也可以使用tftp传输:

# server-side:
sudo uftpd -n -o ftp=0,tftp=69 ./
# 99pi-side
tftp -g -l ssh-xxx -r openssh/bin/ssh-xxx [114.5.1.4]

剩下的后面说。

Vim

tar -zxvf ncurses-6.5.tar.gz && rm ncurses-6.5.tar.gz
cd ncurses-6.5/
./configure --prefix=$HOME/2k300/vim/nc_install --host=loongarch64-unknown-linux-gnu --without-cxx-binding --without-ada --without-progs --without-tests --with-shared
make -j && make install
export TARGET=loongarch64-unknown-linux-gnu

Linux Kernel

参考文档:龙芯2K300.软件uboot用户手册0.2

把linux6.9源码里的

复制到新的内核源码的对应位置,然后

make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- ls2k0300_99_pai_wifi_defconfig
make ARCH=loongarch CROSS_COMPILE=loongarch64-unknown-linux-gnu- -j8

产物:

现在制作vmlinux.bin.lzma

lzma -k ./linux-6.11/arch/loongarch/boot/vmlinux.bin
mv ./linux-6.11/arch/loongarch/boot/vmlinux.bin.lzma ./

创建文件:multi.its,并更新其中的

/*
* U-Boot uImage source file with multiple kernels and ramdisks blobs
*/
/dts-v1/;
/{
    description = "Various kernels and ramdisks blobs";
    #address-cells = <2>;
    images {
        kernel-1 {
            description = "vmlinux";
            data = /incbin/("vmlinux.bin.lzma");
            type = "kernel";
            arch = "loongarch";
            os = "linux";
            compression = "lzma";
            load = <0x90000000 0x00200000>;
            entry = <0x90000000 0x01348000>;
        };
    };
    configurations {
        default = "config-1";
        config-1 {
            description = "vanilla-2.6.23 configuration";
            kernel = "kernel-1";
            loadables = "kernel-1";
        };
    };
};

生成uImage镜像:mkimage -f multi.its uImage

Arch Linux

主要原因是aur比较香,而且软件分发也相对简单,反正pacman作为包管理够用。

北大的LCPU整了个LA64的AUR镜像源:

Arch Linux for Loongarch64

arch安装的核心就是准备一个能跑起来pacstrap的环境,然后就能用pacstrap去准备arch的rootfs了。

意外发现原来有LA64的arch安装iso,这下不用自己准备rootfs了,好耶 居然忘了3A6000已经能用Arch了

哦,忘了,3A6000的abi跟2K0300不太一样,果然最后还是翻车了

解压发现其中的airootfs.sfs,arch下安装squashfs-tools后,使用sudo unsquashfs airootfs.sfs解压rootfs。完成后编译一个uImage,丢到rootfs的/boot下。

准备一个ext4的U盘,将rootfs复制到其中。U盘插入99pi,启动并进入uboot cli,输入:

ext4load usb 0 ${loadaddr} boot/uImage
bootm ${loadaddr}

手动启动系统。

不过启动失败了,查报错感觉问题可能出在指令集不兼容上了,似乎是LA64的SIMD指令在2k300上用不了。

下一步应该就是手动编译一个arch rootfs再安装了。

刷uboot

可以借助tftp刷入,也可以usb刷入。我用了后一种方法:

# 主系统
mkfs.ext2 /dev/sdb    # 格式化U盘
mount /dev/sdb ./tmp
cp u-boot-spl-gz.bin ./tmp/
umount ./tmp
# 99pi
# 插入U盘
# 启动时多次按c进入PMON控制台
fload /dev/fs/ext2@usb0/u-boot-spl-gz.bin

下面是输出:

PMON> fload /dev/fs/ext2@usb0/u-boot-spl-gz.bin                                                            /  
Loading file: /dev/fs/ext2@usb0/u-boot-spl-gz.bin dl_offset 900000000f800000 addr 900000000f800000  
(bin)                                                                                                      |  
Loaded 580432 bytes  
  
Programming flash 900000000f800000:8db50 into 800000001c000000  
Erase end!                                                                                                 /  
Programming end!  
Verifying FLASH. No Errors found.  
PMON>

此时就完成了,可以重启了。

配置uboot参数

setenv bootargs console=ttyS0,115200n8 root=/dev/sda1 rootdelay=3
saveenv

编译busybox最小系统

流程很简单:

    mkdir -p ./{src,}

问题

不知道为啥,换musl-gcc就可以了。

刚开始以为确实是依赖问题,把能想到的玩意都装了一圈之后觉得不对劲上Arch Wiki搜了一下:

[已解决] make menuconfig 和 ncurses 库的问题 / 新手 / Arch Linux 论坛 esp8266-rtos-sdk-aur-ncurses-fix.patch - aur.git - AUR Package Repositories

最后发现是./scripts/kconfig/lxdialog/check-lxdialog.sh的锅。里边的check()函数对main的写法有问题:应该在下图的main()前面加上int才能正常check到是否安装了ncurses库。

我这里是因为menuconfig总是失败所以没法开Build static binary,开开就能跑了。

uboot装系统

uboot支持的功能挺丰富的,有ping有网络还有tftp这几个。

tftpd配置

archlinux底下很好配:

sudo pacman -S tftp-hpa
sudo systemctl enable --now tftp-hpa
sudo chown $USER:$USER /srv/tftp

完了之后就能把uImage文件放进去后在开发板的uboot里下载了。

网络配置

因为网口直连开发板,所以两边都需要固定ip。我用nmtui新增了一个etnernet连接,绑定设备后设置ip和gateway、netmask之后启用就ok了。

# 等价的nmcli配置
nmcli connection add con-name ls2k0300 ifname enp9s0f4u1u1u2 type ethernet ip4 192.168.1.100/24 gw4 192.168.1.1
nmcli connection modify ls2k0300 ipv6.method disabled
nmcli connection modify ls2k0300 connection.autoconnect no
nmcli connection up ls2k0300

现在来到开发板。清空env:

env default -a
saveenv
reset

后重新设置(要清是因为我忘了配某些env所以启动失败):

setenv ipaddr 192.168.1.10      # 开发板IP
setenv serverip 192.168.1.100   # 你的电脑IP
setenv netmask 255.255.255.0

setenv loadaddr 0x9000000090000000
setenv fdt_addr 0x9000000091000000

tftpboot ${loadaddr} uImage

顺利的话内核就能正常启动了。OK的话就保存启动命令:

setenv bootcmd 'ext4load mmc 0:1 ${loadaddr} boot/uImage;bootm ${loadaddr}'
saveenv

然后就是给内核写启动参数挂rootfs之类的:

setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p1 rootwait rw earlycon init=/sbin/init'

root位置根据实际修改就行。

systemd修改网络配置

buildroot用了systemd-networkd,直接配置:

#/etc/systemd/network/20-end0.network
[Match]
Name=end0

[Network]
Address=192.168.1.10/24
Gateway=192.168.1.1
DNS=192.168.1.1

然后systemctl restart systemd-networkd && networkctl up end0网络就ok了。

编译openssl

export CC="${TOOLCHAIN_PREFIX}-gcc"
export AR="${TOOLCHAIN_PREFIX}-ar"
export AS="${TOOLCHAIN_PREFIX}-as"
export LD="${TOOLCHAIN_PREFIX}-ld"
export RANLIB="${TOOLCHAIN_PREFIX}-ranlib"
export STRIP="${TOOLCHAIN_PREFIX}-strip"
export CXX="${TOOLCHAIN_PREFIX}-g++"
export RANLIB="${TOOLCHAIN_PREFIX}-ranlib"

cd $PROJECT_DIR/deps/openssl-3.2.0
make clean

./Configure linux64-loongarch64 --prefix=/usr
make CC="${CC}" AR="${AR}"
make DESTDIR=$SYSROOT install RANLIB=${RANLIB}

编译pacman

上面三个编译好之后就可以开编了:

cd $PROJECT_DIR/deps/pacman
rm -rf build && mkdir build && cd build
cat > ../cross-loongarch64-corrected.txt << 'EOF'
[binaries]
c = 'loongarch64-unknown-linux-gnu-gcc'
cpp = 'loongarch64-unknown-linux-gnu-g++'
ar = 'loongarch64-unknown-linux-gnu-ar'
strip = 'loongarch64-unknown-linux-gnu-strip'
pkgconfig = 'pkg-config'

[properties]
sys_root = '/home/xero/code/ls2k0300/rootfs'
pkg_config_libdir = '/home/xero/code/ls2k0300/rootfs/usr/lib/pkgconfig:/home/xero/code/ls2k0300/rootfs/usr/lib64/pkgconfig'

# LoongArch64优化标志
c_args = [
  '-march=loongarch64',
  '-mtune=la464',
  '-O2',
  '-pipe',
  '-fno-plt',
  '-fstack-protector-strong']

c_link_args = [
  '-Wl,--gc-sections',
  '-Wl,--as-needed',
  '-Wl,-z,now',
  '-Wl,-z,relro']

[host_machine]
system = 'linux'
cpu_family = 'loongarch64'
cpu = 'loongarch64'
endian = 'little'
EOF

meson setup .. \
    --cross-file ../cross-loongarch64-corrected.txt \
    --prefix=/usr \
    -Ddoc=disabled \
    -Ddoxygen=disabled \
    -Dgpgme=disabled \
    -Dcurl=enabled \
    -Dcrypto=openssl \
    -Duse-git-version=false \
    -Dpkg-ext=.pkg.tar.zst \
    -Dscriptlet-shell=/bin/bash \
    -Di18n=false \
    -Dbuildstatic=true
    
ninja
DESTDIR=$SYSROOT ninja install
mkdir -p $SYSROOT/etc/pacman.d
mkdir -p $SYSROOT/var/lib/pacman/sync
mkdir -p $SYSROOT/var/lib/pacman/local
mkdir -p $SYSROOT/var/cache/pacman/pkg

cat > $SYSROOT/etc/pacman.conf << 'EOF'
[options]
Architecture = loongarch64
CheckSpace
# SigLevel = Never
# LocalFileSigLevel = Optional

[core]
Server = https://archlinux.loongarch.org/loongarch64/core
[extra]
Server = https://archlinux.loongarch.org/loongarch64/extra
[community]
Server = https://archlinux.loongarch.org/loongarch64/community
EOF

# 创建mirrorlist
echo "Server = https://archlinux.loongarch.org/loongarch64/\$repo" > $SYSROOT/etc/pacman.d/mirrorlist

cat > $SYSROOT/usr/bin/pacman-key << 'EOF'
#!/bin/bash
echo "Warning: gpgme disabled, signature verification unavailable"
exit 0
EOF
chmod +x $SYSROOT/usr/bin/pacman-key

编译gcc

# mpfr
export LDFLAGS="-Wl,-rpath-link,$SYSROOT/usr/lib -Wl,-rpath-link,$SYSROOT/usr/lib"
export LD_LIBRARY_PATH="$SYSROOT/usr/lib:$LD_LIBRARY_PATH"
./configure --host=$TOOLCHAIN_PREFIX --prefix=/usr     --with-gmp=$SYSROOT/usr     --disable-static  --with-sysroot=$SYSROOT

# mpc
./configure --host=$TOOLCHAIN_PREFIX --prefix=/usr     --with-gmp=$SYSROOT/usr     --with-mpfr=$SYSROOT/usr     --disable-static --with-sysroot=$SYSROOT

# isl - 多面体优化库
./configure --host=$TOOLCHAIN_PREFIX --prefix=/usr \
    --with-gmp-prefix=$SYSROOT/usr \
    --disable-static
    --with-sysroot=$SYSROOT

上面三个依赖搞定之后就能开编gcc了。

# 在编译之前因为编译机环境是x86_64所以临时改下环境变量欺骗makepkg
export MAKEPKG_CONF="$PWD/makepkg.conf"

#PKGBUILD
# Maintainer: Your Name <[email protected]>
pkgname=gcc
pkgver=15.2.0
pkgrel=1
pkgdesc='The GNU Compiler Collection'
arch=('loongarch64')
license=('GPL3' 'LGPL')
url='https://gcc.gnu.org'
depends=('glibc' 'binutils' 'gmp' 'mpfr' 'mpc' 'zlib' 'isl')
makedepends=('flex' 'bison')
options=('!emptydirs' '!strip')
source=("https://mirrors.aliyun.com/gnu/gcc/gcc-$pkgver/gcc-$pkgver.tar.gz"
        "gcc-loongarch64.patch")
sha256sums=('SKIP'
            'SKIP')

prepare() {
  cd gcc-$pkgver
  
  # 应用loongarch64特定补丁(如果需要的话)
  # 如果有补丁文件,可以在这里打补丁
  if [ -f "$srcdir/gcc-loongarch64.patch" ]; then
    patch -p1 -i "$srcdir/gcc-loongarch64.patch"
  fi
  
  # 创建构建目录
  mkdir -p build
}

build() {
  cd gcc-$pkgver/build
  
  # 设置sysroot路径(根据实际情况修改)
  SYSROOT=/home/xero/code/ls2k0300/rootfs
  
  # 配置选项,确保找到GMP、MPFR、MPC
  ../configure \
    --prefix=/usr \
    --host=loongarch64-unknown-linux-gnu \
    --build=x86_64-pc-linux-gnu \
    --target=loongarch64-unknown-linux-gnu \
    --with-sysroot=$SYSROOT \
    --with-gmp=$SYSROOT/usr \
    --with-mpfr=$SYSROOT/usr \
    --with-mpc=$SYSROOT/usr \
    --with-isl=$SYSROOT/usr \
    --enable-languages=c,c++ \
    --enable-shared \
    --enable-threads=posix \
    --enable-checking=release \
    --disable-multilib \
    --disable-bootstrap \
    --with-system-zlib \
    --with-arch=loongarch64 \
    --with-abi=lp64d \
    --disable-werror
  
  make
}

package() {
  cd gcc-$pkgver/build
  
  # 安装到$pkgdir
  make DESTDIR="$pkgdir" install
  
  # 移除不需要的文件
  rm -rf "$pkgdir"/usr/share/man/man7
  rm -rf "$pkgdir"/usr/share/info
}

不行,有点问题,回头再整(

2.9在车上。搜了下报错指向的那俩CFLAGS,对应的是makepkg.conf里设置的值。反正编译用的是交叉工具链,那也不用那俩-mtune参数来指定什么la464loongarch了。

改完后的构建文件:

#makepkg.conf
CARCH="loongarch64"
CHOST="loongarch64-unknown-linux-gnu"
CFLAGS="-O2 -pipe -fno-plt"
# CFLAGS="-march=loongarch64 -mtune=la464 -O2 -pipe -fno-plt"
CXXFLAGS="${CFLAGS}"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
DEBUG_CFLAGS="-g"
DEBUG_CXXFLAGS="-g"
BUILDENV=(!distcc color !ccache check !sign)
OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !debug)
PKGEXT='.pkg.tar.zst'
SRCEXT='.src.tar.gz'

#PKGBUILD
# Maintainer: Your Name <[email protected]>
pkgname=gcc
pkgver=15.2.0
pkgrel=1
pkgdesc='The GNU Compiler Collection'
arch=('loongarch64')
license=('GPL3' 'LGPL')
url='https://gcc.gnu.org'
depends=('glibc' 'binutils' 'gmp' 'mpfr' 'mpc' 'zlib' 'isl')
makedepends=('flex' 'bison')
options=('!emptydirs' '!strip')
source=("https://mirrors.aliyun.com/gnu/gcc/gcc-$pkgver/gcc-$pkgver.tar.gz"
        "gcc-loongarch64.patch")
sha256sums=('SKIP'
            'SKIP')

prepare() {
  cd gcc-$pkgver
  
  # 应用loongarch64特定补丁(如果需要的话)
  # 如果有补丁文件,可以在这里打补丁
  if [ -f "$srcdir/gcc-loongarch64.patch" ]; then
    patch -p1 -i "$srcdir/gcc-loongarch64.patch"
  fi
  
  # 创建构建目录
  mkdir -p build
}

build() {
  cd gcc-$pkgver/build
  
  # 设置sysroot路径(根据实际情况修改)
  SYSROOT=/home/xero/code/ls2k0300/rootfs
  TOOLCHAIN_PREFIX=loongarch64-unknown-linux-gnu
  
  # 配置选项,确保找到GMP、MPFR、MPC
  ../configure \
    --prefix=/usr \
    --host=loongarch64-unknown-linux-gnu \
    --build=x86_64-pc-linux-gnu \
    --target=loongarch64-unknown-linux-gnu \
    --with-sysroot=$SYSROOT \
    --with-gmp=$SYSROOT/usr \
    --with-mpfr=$SYSROOT/usr \
    --with-mpc=$SYSROOT/usr \
    --with-isl=$SYSROOT/usr \
     --with-arch=loongarch64 \
     --with-abi=lp64d \
    --enable-languages=c,c++ \
    --enable-shared \
    --enable-threads=posix \
    --enable-checking=release \
    --disable-multilib \
    --disable-bootstrap \
    --disable-werror \ 
CC="${TOOLCHAIN_PREFIX}-gcc" \
CXX="${TOOLCHAIN_PREFIX}-g++" \
AR="${TOOLCHAIN_PREFIX}-ar" \
RANLIB="${TOOLCHAIN_PREFIX}-ranlib" \
LD="${TOOLCHAIN_PREFIX}-ld" \
STRIP="${TOOLCHAIN_PREFIX}-strip" \
CFLAGS="-I$SYSROOT/usr/include" \
LDFLAGS="-L$SYSROOT/usr/lib -Wl,-rpath-link,$SYSROOT/usr/lib" \
LD_LIBRARY_PATH="$SYSROOT/usr/lib:$LD_LIBRARY_PATH" 

#     --with-system-zlib \
  
  make -j 16
}

package() {
  cd gcc-$pkgver/build
  
  # 安装到$pkgdir
  make DESTDIR="$pkgdir" install
  
  # 移除不需要的文件
  rm -rf "$pkgdir"/usr/share/man/man7
  rm -rf "$pkgdir"/usr/share/info
}

有一些依赖比如zlib忘了编译进去,所以可能会少点功能。

好吧因为下载的gcc源码版本太新了导致交叉编译工具链构建失败了。改版本重新下了。工具链是13.2.0,所以下载也下13.2.0应该就ok了。

还真是,编译一把过。

neofetch

下了aur,里面是直接clone github repo,直接换成gitee mirror一把梭哈

不过这好像是纯shell软件,象征性打个包。arch=('any')的含金量不必多言。

有了前面的 gcc之后,之后的包应该都能直接去开发板上编译了(就是性能不太可观

移植base

安装devtools。然后用pkgctl repo clone --protocol=https base下下来基础的包。

然后依照它里面的依赖逐个用pkgctl把pkgbuild下下来,挨个处理。