15AH, San Francisco

California, United States.

Send Your Mail At:

tianyingkejishe@sina.cn

Working Hours

Mon-Sat: 9.30am To 7.00pm

作者标题

Autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et dolore feugait.

Author Archive by stormwind

【uboot】飞腾s5000的uboot环境变量

Environment size: 1420/4092 bytes
S5000C#
arch=arm
baudrate=115200
board=s5000c
board_name=s5000c
boot_fdt=booti 0x90000000 - 0x95000000
boot_usb_fdt=booti 0x90000000 - 0x95000000
bootargs=console=ttyAMA1,115200 earlycon=pl011,0x20001000 root=/dev/sda2 rootdelay=10 rw
bootcmd=run distro_bootcmd
bootdelay=3
cpu=armv8
distro_bootcmd=run load_kernel; run load_fdt; run boot_fdt
ethaddr=11:22:33:44:55:66
ext4_read_check=ext4load scsi 0:1 0x92000000 file_bake.txt
ext4_read_test=ext4load scsi 0:1 0x90000000 dtb/ft2004.dtb
ext4_write_test=ext4write scsi 0:1 0x90000000 /file_bake.txt 0x2DA8
fat_read_check=fatload usb 0:1 0x92000000 file_bake.txt
fat_read_test=fatload usb 0:1 0x90000000 md5sum.txt
fat_write_test=fatwrite usb 0:1 0x90000000 /file_bake.txt 0x5D4A
fdtcontroladdr=f9b40a70
fileaddr=95000000
filesize=87b7
gatewayip=192.168.1.1
ipaddr=192.168.1.250
load_fdt=ext4load scsi 0:1 0x95000000 s5000c-64c.dtb
load_kernel=ext4load scsi 0:1 0x90000000 Image
load_usb_fdt=fatload usb 0:1 0x95000000 s5000c-64c.dtb
load_usb_kernel=fatload usb 0:1 0x90000000 Image
loadaddr=0x90000000
netmask=255.255.255.0
serverip=192.168.1.110
soc=s5000c
start_autoscript=if usb start; then run start_usb_autoscript; fi; if scsi info; then run start_ssd_autoscript; fi;
start_ssd_autoscript=run load_kernel; run load_fdt; run boot_fdt
start_usb_autoscript=run load_usb_kernel; run load_usb_fdt; run boot_usb_fdt
stderr=serial
stdin=serial,usbkbd
stdout=serial
vendor=phytium

【DPDK】编译流程

一、编译环境准备

  • General development tools including a C compiler supporting the C11 standard, including standard atomics, for example: GCC (version 8.0+ recommended) or Clang (version 7+ recommended), and pkg-config or pkgconf to be used when building end-user binaries against DPDK.
    • For RHEL systems these can be installed using dnf groupinstall "Development Tools"
    • For Fedora systems these can be installed using dnf group install development-tools
    • For Ubuntu/Debian systems these can be installed using apt install build-essential
    • For Alpine Linux, apk add alpine-sdk bsd-compat-headers
  • Python 3.6 or later.
  • Meson (version 0.57+) and ninja
    • meson & ninja-build packages in most Linux distributions
    • If the packaged version is below the minimum version, the latest versions can be installed from Python’s “pip” repository: pip3 install meson ninja
  • pyelftools (version 0.22+)
    • For Fedora systems it can be installed using dnf install python-pyelftools
    • For RHEL/CentOS systems it can be installed using pip3 install pyelftools
    • For Ubuntu/Debian it can be installed using apt install python3-pyelftools
    • For Alpine Linux, apk add py3-elftools
  • Library for handling NUMA (Non Uniform Memory Access).
    • numactl-devel in RHEL/Fedora;
    • libnuma-dev in Debian/Ubuntu;
    • numactl-dev in Alpine Linux
$ cd /usr/src/
$ wget https://fast.dpdk.org/rel/dpdk-21.11.tar.xz
$ tar xf dpdk-21.11.tar.xz
$ export DPDK_DIR=/usr/src/dpdk-21.11
$ cd $DPDK_DIR
$ export DPDK_BUILD=$DPDK_DIR/build
$ meson setup build-arm64

$ ninja -C build
$ sudo ninja -C build install
$ sudo ldconfig
$ pkg-config --modversion libdpdk

【DPDK]交叉编译

一、环境准备

sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
sudo apt install meson ninja pkg-config gcc-multilib

二、创建交叉编译配置文件

[binaries]
# 交叉编译器路径(绝对路径/系统PATH中的别名)
c = 'aarch64-linux-gnu-gcc'
cpp = 'aarch64-linux-gnu-g++'
ar = 'aarch64-linux-gnu-ar'
strip = 'aarch64-linux-gnu-strip'
pkgconfig = 'pkg-config'  # 若目标机有 pkg-config,可指定目标机路径
ninja = '/usr/bin/ninja'

[host_machine]
# 目标架构:根据实际修改(aarch64/armv7l/mips64等)
system = 'linux'
cpu_family = 'aarch64'
cpu = 'cortex-a72'  # 目标CPU型号(可选,如 cortex-a53、x86_64)
endian = 'little'

[properties]
# 目标机内核头文件路径(关键!必须匹配目标机内核版本)
c_args = ['-I/path/to/target/linux-headers-5.15.0-101-arm64/include']
c_link_args = ['-L/path/to/target/lib64', '-lpthread', '-ldl']
# 禁用宿主机依赖检测,强制使用交叉编译环境
pkg_config_libdir = ['/path/to/target/usr/lib/aarch64-linux-gnu/pkgconfig']
# DPDK 特有配置:禁用不支持的驱动/功能
dpdk_cross = true
dpdk_disable_drivers = 'net/e1000,net/ixgbe'  # 禁用目标机无的网卡驱动
dpdk_enable_kmods = false  # 交叉编译时不编译内核模块(目标机单独编译)
  • 确保配置文件无中文、特殊符号(如「・」「¥」),仅用 ASCII 字符;
  • 验证文件编码:
file -i dpdk_cross_arm64.txt
# 输出:charset=utf-8 → 正常;若为 gbk/iso-8859-1,需转换
iconv -f GBK -t UTF-8 dpdk_cross_arm64.txt -o dpdk_cross_arm64_utf8.txt

三、DPDK 交叉编译实操

1. 源码准备

# 下载 DPDK 源码(以 22.11 为例)
wget https://fast.dpdk.org/rel/dpdk-22.11.tar.xz
tar -xf dpdk-22.11.tar.xz
cd dpdk-22.11

2. 初始化 Meson 构建目录

通过 --cross-file 指定交叉配置文件,同时设置关键参数:

# 创建构建目录
meson setup build-arm64 \
  --cross-file=/path/to/dpdk_cross_arm64.txt \
  --prefix=/opt/dpdk-arm64  # 编译后安装路径

3. 编译与安装

# 编译(-j 后跟核心数,加速编译)
ninja -C build-arm64 -j$(nproc)

# 安装到指定路径
ninja -C build-arm64 install

【Linux】error: macro “__TIME__” might prevent reproducible builds [-Werror=date-time]

解决方法有如下几种,可根据需求进行选择

第一种解决方法 在makefile中添加如下选项

EXTRA_CFLAGS += -Wno-error=date-time
EXTRA_CFLAGS +=-Wno-date-time

 注意:在第二段定位中已经说到只有在4.9以及之后的gcc版本中才有这两个选项,如果你在gcc版本小于4.9的系统上编译,比如在centos7.2系统中,centos中默认的gcc版本是4.8.5,编译时就会报"cc1: 错误:-Werror=date-time:没有选项 -Wdate-time"错误,所以这种解决方法如果只是使用4.9以上的gcc版本是没有问题的;


 第二种解决方法
修改/lib/modules/'uname -r'/build/Makefile文件,我的是/lib/modules/4.4.0-116-generic/build/Makefile
将KBUILD_CFLAGS   += $(call cc-option,-Werror=date-time)这一行注释掉



注意:这种方法虽然解决了这个问题,但是修改了系统本身的属性,不太推荐

第三种解决方法

这一种方法也是我比较推荐的方法,修改内核模块的makefile文件,添加一行

ccflags-y+=$(shell if [ $(call cc-version) -ge 0490 ] ; then echo "-Wno-error=date-time -Wno-date-time"; fi ;)

在linux内核的最顶层目录也就是根目录下面的Makefile文件中,有一个变量"KBUILD_CFLAGS",这个$(KBUILD_CFLAGS)中存放的是传递给gcc编译器的编译选项,如果被编译的文件在被gcc编译时,没有特殊的要求的话就会使用$(KBUILD_CFLAGS)中的编译选项。



 但是如果被gcc编译的文件有特殊的编译选项要求的话,使用如下的方式来指定编译选项:

 ccflags-y,是指定给$(CC)的编译选项;

 asflags-y,是指定给$(AS)的编译选项;

 ldflags-y,是指定给$(LD)的编译选项;

【Linux】linux5.10内核do_gettimeofday函数报错问题

linux5.10内核do_gettimeofday函数提示不存在。

解决办法使用ktime_get_real_ts64代替。

具体实例:

修改之前代码:

    struct  timeval   time_now;
	struct rtc_time tm; 
    do_gettimeofday(&time_now);
	rtc_time_to_tm(time_now.tv_sec, &tm); 

修改之后代码:

	struct timespec64 ts64;
	struct rtc_time tm; 
    ktime_get_real_ts64(&ts64);
	tm = rtc_ktime_to_tm(ts64.tv_sec); 

【Ubuntu】飞腾s5000c移植国产网卡WX1860AL2驱动

硬件平台:

国产飞腾芯片s5000c-16

国产网讯网卡WX1860AL2

软件平台:

Distributor ID: Ubuntu
Description: Ubuntu Built with Buildroot, based on Ubuntu 22.04 LTS
Release: 22.04
Codename: jammy

1、获取网卡驱动

直接从官网下载就好,本实现使用的版本:ngbe-1.2.7.zip

2、编译安装(一定要在目标机操作)

不同平台上编译,安装的命令不同:

Kylin V10/银河麒麟 操作系统:

编译:

make CHNOS=KYLIN

安装:

make CHNOS=KYLIN modules_install

或者

make CHNOS=KYLIN install

UOS 操作系统:

编译:

make CHNOS=UOS

安装

make CHNOS=UOS modules_install

或者

make CHNOS=UOS install

Euler 操作系统:

编译:

make CHNOS=EULER

安装:

make CHNOS=EULER modules_install

或者

make CHNOS=EULER install

其他平台操作系统:

编译:

make

安装:make modules_install

或者

make install

4) 加载驱动:

modprobe txgbe (仅安装完首次需要手动加载,若重启系统,系统会自动加载驱动)。

5)查看驱动是否加载成功:

[root@SW ~]# lsmod | grep txgbe

txgbe 208399 0

表明驱动已经加载上。

3、卸载驱动

1)显示已安装的驱动:

[root@localhost ~]# lsmod | grep txgbe

txgbe 385024 0

2)卸载驱动:rmmod txgbe

[root@localhost ~]# rmmod txgbe

3) 再次查看已安装的驱动,已经没有 txgbe 驱动。

[root@localhost ~]# lsmod | grep txgbe

4、参考资料

5、适配后的网卡驱动

【Linux】内核log打印级别设置

1. 日志级别控制

  • 查看当前日志级别cat /proc/sys/kernel/printk # 输出:4 4 1 7 → 当前控制台阈值为4
  • 启用 pr_info 输出(需级别 ≤6):echo 7 > /proc/sys/kernel/printk # 将阈值设为7(允许INFO及以上日志输出)
  • 持久化配置:在 /etc/sysctl.conf 添加 kernel.printk = 7 4 1 77

2. 查看输出日志

  • 实时监控dmesg -w # 动态显示内核日志
  • 筛选特定日志dmesg --level=info # 仅显示INFO级别日志

[Arm]version magic ‘5.6.0-rc5+ SMP mod_unload ‘ should be…问题研究

1, 首先,为什么会出现修改了kernel重新编译后magic num改变
内核版本是如何生成的:

Linux 内核在进行模块装载时先完成模块的 CRC 值校验,再核对 vermagic 中的字符信息,linux版本在 include/generated/utsrelease.h中定义,文件中的内容如下:

#define UTS_RELEASE "4.9.123"

utsrelease.h是kernel编译后自动生成的,用户更改里面的内容不会有效果。
这个值可以通过修改最顶层的Makefile文件来修改。

VERSION = 4
PATCHLEVEL = 9                
SUBLEVEL = 123                
EXTRAVERSION =
...

init/version.c中,定义了kernel启动时的第一条打印信息:

/* FIXED STRINGS! Don't touch! */
const char linux_banner[] =
  "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
  LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";

const char linux_proc_banner[] =
  "%s version %s"
  " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
  " (" LINUX_COMPILER ") %s\n";

这里UTS_RELEASE在kernel编译时自动生成

init/main.casmlinkage __visible void __init start_kernel(void)函数中,有kernel启动的第一条打印信息,这条信息是dmesg命令打印出来:

pr_notice("%s", linux_banner);

驱动模块的version magic信息是怎么生成的:

4.x 内核下,在include/linux/vermagic.h中定义有VERMAGIC_STRING,如下:

#include <generated/utsrelease.h>
              
/* Simply sanity version stamp for modules. */
#ifdef CONFIG_SMP
#define MODULE_VERMAGIC_SMP "SMP "
#else
#define MODULE_VERMAGIC_SMP ""
#endif
#ifdef CONFIG_PREEMPT
#define MODULE_VERMAGIC_PREEMPT "preempt "
#else
#define MODULE_VERMAGIC_PREEMPT ""
#endif
#ifdef CONFIG_MODULE_UNLOAD
#define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload "
#else
#define MODULE_VERMAGIC_MODULE_UNLOAD ""
#endif 
#ifdef CONFIG_MODVERSIONS
#define MODULE_VERMAGIC_MODVERSIONS "modversions "
#else
#define MODULE_VERMAGIC_MODVERSIONS ""
#endif
#ifndef MODULE_ARCH_VERMAGIC
#define MODULE_ARCH_VERMAGIC ""
#endif  

#define VERMAGIC_STRING             \
  UTS_RELEASE " "             \
  MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT       \
  MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
  MODULE_ARCH_VERMAGIC

VERMAGIC_STRING不仅包含内核版本号,还包含有内核使用的SMP与preempt, MODULE_UNLOAD, 架构等配置信息。模块在编译时,我们可以看到屏幕上会显示”MODPOST”。

  <~/Documents/Demo/driver/debugfs> make
make -C ~/kernel/ SUBDIRS=~/Documents/Demo/driver/debugfs modules
make[1]: Entering directory '~/kernel'
  CC [M]  ~/Documents/Demo/driver/debugfs/my_debugfs.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      ~/Documents/Demo/driver/debugfs/my_debugfs.mod.o
  LD [M]  ~/Documents/Demo/driver/debugfs/my_debugfs.ko
make[1]: Leaving directory '~/kernel'

在此阶段, VERMAGIC_STRING会添加到模块的modinfo段。在内核源码目录下scripts\mod\modpost.c文件中可以看到模块后续处理部分的代码。模块编译生成后,通过modinfo my_debugfs.ko命令可以查看此模块的vermagic等信息。

  <~/Documents/Demo/driver/debugfs> modinfo my_debugfs.ko 
filename:      ~/Documents/Demo/driver/debugfs/my_debugfs.ko
license:        GPL
depends:        
vermagic:       4.9.123 SMP preempt mod_unload aarch64

4.x 内核下的模块装载器里保存有内核的版本信息,在装载模块时,装载器会比较所保存的内核vermagic与此模块的modinfo段里保存的vermagic信息是否一致,两者一致时,模块才能被装载。

为了使两个版本一致:可以把 依赖源码中的include/linux/vermagic.h中的UTS_RELEASE修改成与目标机器的版本一致,这样,再次编译模块就可以了。

内核模块版本和内核版本不一致的处理方法

2, 发现版本号会追加git的版本号,还有个“+”
向linux内核版本号添加字符/为何有时会自动添加“+”号,根据这篇文章,一步一步试一下

第一步:去掉git的附加信息
先在menuconfig中找到

  │ Symbol: LOCALVERSION [=]                                                                                                                                                                                   │  
  │ Type  : string                                                                                                                                                                                             │  
  │ Prompt: Local version - append to kernel release                                                                                                                                                           │  
  │   Location:                                                                                                                                                                                                │  
  │ (1) -> General setup                                                                                                                                                                                       │  
  │   Defined at init/Kconfig:81                                                                                                                                                                               │  
  │                                                                                                                                                                                                            │  
  │                                                                                                                                                                                                            │  
  │ Symbol: LOCALVERSION_AUTO [=n]                                                                                                                                                                             │  
  │ Type  : boolean                                                                                                                                                                                            │  
  │ Prompt: Automatically append version information to the version string                                                                                                                                     │  
  │   Location:                                                                                                                                                                                                │  
  │ (2) -> General setup                                                                                                                                                                                       │  
  │   Defined at init/Kconfig:91                                                                                                                                                                               │  
  │   Depends on: !COMPILE_TEST [=n]                                                                                                                                                                           │  
  │                                                           

关掉LOCALVERSION_AUTO并留空LOCALVERSION,发现git版本确实是不见了,但是‘+’还是存在。

第二步:去掉“+”号

scripts/setlocalversion文件中,找到以下语句:

# CONFIG_LOCALVERSION and LOCALVERSION (if set)
res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"

# scm version string if not at a tagged commit
if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
  # full scm version string
  res="$res$(scm_version)"
else
  # append a plus sign if the repository is not in a clean
  # annotated or signed tagged state (as git describe only
  # looks at signed or annotated tags - git tag -a/-s) and
  # LOCALVERSION= is not specified
  if test "${LOCALVERSION+set}" != "set"; then
    scm=$(scm_version --short)
   # res="$res${scm:++}"	//××××××××××××××注释掉这句话××××××××××××
  fi
fi

下面是注释前后的对比

注释前
在这里插入图片描述

问题解决。

Note:在网上还看到两种方法,写在下面:第一种:menuconfig 的时候不要勾选,直接搜MODVERSIONS

注意不要选图中那行

第二种:modprobe –force-vermagic helloworld.ko

这个大家可以自行尝试一下