在RK的sdk中有制作update的工具二进制,但是这些二进制是只能运行在x86平台上。而我们的工作环境大部分情况下是在arm64上的,本篇文章提供了在arm64下能够打包update的方法。
https://gitlab2.kylin.com/shanghai-team/create-rootfs/-/tree/kybuild/tool/src
如上是工具的源码,可以通过make的方式在各个平台上编译生成afptool和img_maker两个二进制
目录附带了一个mkupdate.sh脚本,通过此脚本可以自动打包固件,如下为脚本内容
#!/bin/bash # Self Test CHIP=$1 usage() { echo "Usage: ./$(basename $0) rk3399 ./$(basename $0) rk3568 ./$(basename $0) rk3588" } if ! [ "${CHIP}" = "rk3399" ] && ! [ "${CHIP}" = "rk3568" ] && ! [ "${CHIP}" = "rk3588" ] then echo -e "\e[32mUnsupported Chip\e[0m" usage exit fi [ ! -d ./Image ] && echo "Cannot found Image directory" && exit ./afptool -pack ./ firmware_afp.img <<! # rk3399 ./img_maker -rk3399 ./Image/MiniLoaderAll.bin firmware_afp.img update.img # rk3568 ./img_maker -rk3588 ./Image/MiniLoaderAll.bin firmware_afp.img update.img # rk3588 ./img_maker -rk3568 ./Image/MiniLoaderAll.bin firmware_afp.img update.img ! ./img_maker -${CHIP} ./Image/MiniLoaderAll.bin firmware_afp.img update.img
在mkupdate.sh的当前目录,需要存在一个打包文件,里面描述了需要打包固件的名字和路径,该文件有自行编写,示例如下:
package-file package-file bootloader Image/MiniLoaderAll.bin parameter Image/parameter.txt trust Image/trust.img uboot Image/uboot.img boot Image/boot.img rootfs Image/rootfs.img
上述描述了需要打包的内容如,自身package-file,bootloader,分区表parameter,trust固件,uboot固件,内核固件boot,根文件系统rootfs
mkupdate.sh需要一个Image目录,其中存放打包中需要的文件,我们要将需要打包的二进制手动拷贝到当前目录的Image目录内后方可运行测试脚本,其文件对应package-file的指定内容
分区文件主要指定了固件的分区细节,该文件根据平台自定义,rk3588的分区文件示例如下
FIRMWARE_VER: 1.0 MACHINE_MODEL: RK3588 MACHINE_ID: 007 MANUFACTURER: RK3588 MAGIC: 0x5041524B ATAG: 0x00200800 MACHINE: 0xffffffff CHECK_MASK: 0x80 PWR_HLD: 0,0,A,0,1 TYPE: GPT CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00040000@0x00008000(boot:bootable),0x01508000@0x00048000(rootfs),0x00600000@0x01550000(data),0x00600000@0x01b50000(work),-@0x02150000(userdata:grow) uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9 uuid:boot=7A3F0000-0000-446A-8000-702F00006273
一般情况下只修改分区文件的cmdline中的分区地址,其他无需改变
mkupdate.sh会在本地目录生成一个update.img,该文件即rk平台的固件格式,可以通过RK的工具进行整包烧录
https://gitlab2.kylin.com/shanghai-team/create-rootfs/-/tree/kybuild/tool/src/windows-tool
上述提供了2.92版本的烧录工具,我们自行开发的arm64的打包工具在此版本正常工作,其他版本尚未验证,无法保障。因为工具为自行修改,和RK的实现不一致,故可能出现windows烧录工具的版本不一样导致出现的烧录异常问题。
如RK更新了超过2.92版本的烧录工具,后续我们会再自行验证和兼容。
随着AI智能的发展,继传统的CPU和GPU之后,又推出了许多更适用于AI学习的芯片,本文就NPU芯片如何在RK平台提供的SDK基础上开发做一个介绍。
NPU全称为Neural network Processing Unit,即神经网络处理器。
可以在110服务器获取 /home/develop/rk/project/Rockchip_RK356X_RKNN_SDK_V0.7.0_20210402
这里 RKNN_API_for_RK356X 里面主要包含了linux和android系统对于如何使用模型文件调用NPU进行AI运算的demo。
rknn-toolkit 是用于将其他神经网络训练架构模型如何转化为 rknn 架构模型的demo,它分为了docker和nodocker版本,建议使用docker版,因为nodeocker版本对于python-3和pip软件版本的要求比较严格,环境不太好搭建。
这里我使用含docker版本举例。
正常加载后,就可以进入docker环境 如下,
docker run -t -i --privileged -v /home/kylin/:/home/kylin/ rknn-toolkit2:0.7.0 /bin/bash
执行后命令行的前缀会改变。
进入docker环境后,进入 rknn-toolkit2-0.7.0/examples/
目录下,可以看到包含了一些以比较常见的神经网络训练框架命名的文件夹。
这里我们以caffe为例,将 caffemodule 转换为 rknnmodule。
进入 caffe/vgg-ssd/ 文件夹,其是转换 caffemodule 的一个demo 。里面使用了 deploy_rm_detection_output.prototxt 文件中提供的图层模型,把 caffemodule 通过 rknn.api 转换为了 rknnmodule 。重点包含以下几个函数:
可以看到流程和RK给出的文档中一致,按照步骤操作即可。
这里会需要一个 caffemodule 的训练模型,可以通过
https://eyun.baidu.com/s/3jJhPRzo , password is rknn
进行下载。
然后执行 python test.py
运行脚本,执行成功后就可以看到文件夹中多了 .rknn 为后缀的文件,它就是rk平台的模型。
这里就完成了模型的转换,过程中可能会根据模型效率/准确度的需求修改一些参数,可以参考SDK中的文档进行调整。
上面我们已经得到了后缀为 .rknn 的模型文件,现在我们就来讲解如何在RK平台使用模型通过NPU进行图像的解析操作。其实上面在转换模型时已经使用python脚本进行了图像解析的示例,本章介绍demo中通过C语言调用RKNN接口的过程。
进入 RKNN_API_for_RK356X_v0.7_20210402/examples/rknn_ssd_demo/
文件夹,可以看到
我们先看看源码调用流程
跟文档流程一致,其中多了一步 postProcessSSD ,这是将结果中的值转换为图片中的坐标点,用于后面画框所用。
看完了源代码我们可以编译应用。这里的环境是rk3568开发板+麒麟v10系统,所以直接执行
build-linux.sh
脚本。
完成后可以看到生成了 rknn_ssd_demo 的二进制文件,接下来我们使用它看看效果。
执行
./build/build_linux_aarch64/rknn_ssd_demo ./model/ssd_inception_v2.rknn ./model/road.bmp
第一个参数是我们生成的二进制文件
第二个参数是 .rknn 为后缀的module模型文件
第三个参数是要被检测的图片。执行后在本地文件夹中生成了 out.jpg 图片
输出如下
可以看到,模型在上图中成功识别到了行人和车辆的位置。
如何判断是否调用到了NPU去处理的上面图像呢。我们可以通过中断:
如果调用到NPU,中断号会增加。
内核中还提供了调整NPU频率的接口:
查看NPU支持的模式,默认为 simple_ondemand
查看NPU当前的频率
echo performance > /sys/devices/platform/fde40000.npu/devfreq/fde40000.npu/governor
调整NPU的工作模式为性能模式(保持最大频率)
查看NPU当前工作状态,@之前为占用率,之后为当前频率
根据内核log,可以判断NPU是否被加载成功,从中也可以看出NPU包含了iommu模块,对内存读写进行了优化。
瑞芯微平台通常通过烧录的方式来更新系统,但是在一些项目评估的过程中,客户经常需要要求能够安装系统,为了让RK平台支持U盘安装,需要稍微在uboot进行修改,使得uboot阶段能够正常的加载到U盘的uImage,uInitrd,dtb文件即可。主要介绍如下
这里是U盘安装内U盘文件内容,主要分为
boot目录 内包含uboot启动所需要的uImage和uInitrd以及sysboot启动需要的extlinux.conf。主要用于启动安装系统 casper目录 内包含rockchip平台所需要的镜像文件 logo.bmp和logo_kernel.bmp 是安装中所需要的开机图片,如果需要使用其他开机图片,可以单独修改替换此图片即可 autorun.inf 和 kylin.ico 是U盘自动运行文件和U盘图标文件
文件内容如下
default install menu title Installer prompt 0 timeout 10 label install menu label kylinos installer linux /boot/uImage initrd /boot/uInitrd append console=tty0 loglevel=0
这里设置默认启动了uImage和uInitrd
文件内容如下
FIRMWARE_VER: 1.0 MACHINE_MODEL: RK3588 MACHINE_ID: 007 MANUFACTURER: RK3588 MAGIC: 0x5041524B ATAG: 0x00200800 MACHINE: 0xffffffff CHECK_MASK: 0x80 PWR_HLD: 0,0,A,0,1 TYPE: GPT CMDLINE: mtdparts=rk29xxnand:0x00004000@0x00004000(uboot),0x00002000@0x00008000(misc),0x00080000@0x0000a000(boot:bootable),0x00800000@0x0008a000(backup),0x01400000@0x0088a000(rootfs),-@0x01c8a000(userdata:grow) uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
这里是安装过程中,需要对系统分区的描述文件。同RK平台的parameter.txt文件
这是支持机器的uboot通过默认usb启动的uboot镜像,如果需要使用U盘安装,则需要更新原先uboot镜像为此镜像。此镜像基于uboot额外做了如下措施
uboot内置设备树,确保uboot下usb功能正常 uboot内默认usb启动优先 uboot内默认支持u盘内开机图片显示
这是RK平台的loader 二进制文件,这里需要放置两个文件,安装时是用的idblock.bin,烧录的时候是用的rk3588_spl_loader_xxx.bin。
diff --git a/configs/rockchip-linux.config b/configs/rockchip-linux.config index 3003d81..cee40ce 100644 --- a/configs/rockchip-linux.config +++ b/configs/rockchip-linux.config @@ -5,3 +5,6 @@ CONFIG_DM_PCA953X=y CONFIG_SPL_FIT_IMAGE_KB=4096 CONFIG_CHECK_VERSION_CHOOSE_DTB=y CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y +CONFIG_EMBED_KERNEL_DTB=y +CONFIG_EMBED_KERNEL_DTB_PATH="dts/rockchip-evb_rk3588.dtb" +CONFIG_EMBED_KERNEL_DTB_ALWAYS=n 2.2 开机显示特定logo diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 9ed6b98..c1ec5e2 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -29,6 +29,7 @@ #define BOOTENV_SHARED_BLKDEV_BODY(devtypel) \ "if " #devtypel " dev ${devnum}; then " \ "setenv devtype " #devtypel "; " \ + "rockchip_show_logo;" \ "run scan_dev_for_boot_part; " \ "fi\0"
diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h index 002dcd6..0566ece 100644 --- a/include/configs/rockchip-common.h +++ b/include/configs/rockchip-common.h @@ -162,7 +162,14 @@ "setenv devtype ramdisk; setenv devnum 0;" \ "fi; \0" -#if defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE) +#if defined(CONFIG_EMBED_KERNEL_DTB) +#define RKIMG_BOOTCOMMAND \ + "run usb_boot;" \ + "boot_android ${devtype} ${devnum};" \ + "boot_fit;" \ + "bootrkp;" \ + "run distro_bootcmd;" +#elif defined(CONFIG_AVB_VBMETA_PUBLIC_KEY_VALIDATE)
修改: drivers/tty/vt/selection.c 修改: drivers/tty/vt/vt.c 修改: drivers/video/fbdev/core/bitblit.c 修改: drivers/video/fbdev/core/fbcon.c 修改: drivers/video/fbdev/core/fbcon.h 修改: drivers/video/fbdev/core/fbcon_ccw.c 修改: drivers/video/fbdev/core/fbcon_cw.c 修改: drivers/video/fbdev/core/fbcon_rotate.c 修改: drivers/video/fbdev/core/fbcon_ud.c 修改: include/linux/fb.h 修改: include/linux/font.h 修改: lib/fonts/Kconfig 修改: lib/fonts/Makefile 新文件: lib/fonts/font_cjk_16x16.c 新文件: lib/fonts/font_cjk_16x16.h 新文件: lib/fonts/font_cjk_32x32.c 新文件: lib/fonts/font_cjk_32x32.h 修改: lib/fonts/fonts.c
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-pc.dtsi index e49f5fa..ff182b1 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-pc.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-pc.dtsi @@ -10,7 +10,7 @@ / { chosen: chosen { - bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.gicv3_pseudo_nmi=0 root=PARTLABEL=rootfs rootfstype=ext4 ro rootwait overlayroot=device:dev=PARTLABEL=userdata,fstype=ext4,mkfs=1 coherent_pool=1m systemd.gpt_auto=0 cgroup_enable=memory swapaccount=1 net.ifnames=0"; + bootargs = "earlycon=uart8250,mmio32,0xfeb50000 irqchip.gicv3_pseudo_nmi=0 root=PARTLABEL=rootfs rootfstype=ext4 ro rootwait overlayroot=device:dev=PARTLABEL=userdata,fstype=ext4,mkfs=1 coherent_pool=1m systemd.gpt_auto=0 cgroup_enable=memory swapaccount=1 net.ifnames=0"; };
diff --git a/arch/arm64/configs/linux.config b/arch/arm64/configs/linux.config index 9a23fc2..6c569cd 100644 --- a/arch/arm64/configs/linux.config +++ b/arch/arm64/configs/linux.config @@ -6,6 +6,7 @@ CONFIG_TOUCHSCREEN_HX83102=y CONFIG_CAN=y CONFIG_CANFD_ROCKCHIP=y CONFIG_OVERLAY_FS=y +CONFIG_EXFAT_FS=y CONFIG_SND_SOC_FIREFLY_MULTICODECS=y
diff --git a/boot.its b/boot.its index 755005c..885bfd1 100644 --- a/boot.its +++ b/boot.its @@ -45,6 +45,21 @@ algo = "sha256"; }; }; + + ramdisk { + description = "Compressed Initramfs"; + data = /incbin/("ramdisk"); + type = "ramdisk"; + arch = "arm64"; + os = "linux"; + compression = "none"; + load = <0x00000000>; + entry = <0x00000000>; + + hash { + algo = "sha256"; + }; + }; }; configurations { @@ -55,6 +70,7 @@ fdt = "fdt"; kernel = "kernel"; multi = "resource"; + ramdisk = "ramdisk";
参考仓库 https://gitlab2.kylin.com/shanghai-team/ramdisk/-/tree/ramdisk-trial
开机运行如下
function start_install() { parse_cmdline prepare_iso if [ "${TRIAL}" == "true" ];then overlay_start return 0 fi while true do clear info "感谢使用麒麟系统,请选择安装模式" info "1) 试用" info "2) 安装" info "3) 调试" info "4) 重启" info "请输入:" read -s -n1 -t 30 -r option case ${option} in 1) overlay_start return 0 ;; 2) _start_install ;; 3) debug_shell ;; 4) echo b > /proc/sysrq-trigger info "你的系统不支持重启" ;; *) [ -z ${option} ] && _start_install ;; esac done }
至此,已经可以获得基于RK3588上使用U盘安装系统的全套方案。客户如果需要设备支持U盘安装,则只需要设备的uboot代码和kernel代码即可正常配置。下面链接版本是支持一款板卡的uboot安装ISO镜像。
随着git项目越来越多,每次环境部署的时候,不可能一个一个去clone仓库,这样太费事了。为了偷懒,我借鉴了android的repo机制,这样可以自行对自己的git仓库搭建一个简单的repo,之后使用这个repo就能方便的管理多个git仓库了。
git clone https://gerrit.googlesource.com/git-repo
如果上网不方便,可以克隆本地仓库。
git clone http://10.3.4.182/arm-embedded/git-repo.git -b kylin-server-130-31
由于repo会把repo url默认到 https://gerrit.googlesource.com/git-repo
。这里修改成130.31的本地git地址。也可修改成gitlab地址。
如:REPO_URL = 'http://10.3.4.182/arm-embedded/git-repo.git'
[root@localhost git-repo]# git diff diff --git a/repo b/repo index 3a51cce..c084b65 100755 --- a/repo +++ b/repo @@ -142,8 +142,6 @@ if __name__ == '__main__': REPO_URL = os.environ.get('REPO_URL', None) if not REPO_URL: REPO_URL = 'https://gerrit.googlesource.com/git-repo' +# kylin local repo url + REPO_URL = 'root@172.25.130.31:/root/work2/git/git-repo.git' REPO_REV = os.environ.get('REPO_REV') if not REPO_REV: REPO_REV = 'stable'
如果不做上述修改,则需要在repo init的时候,加入 --repo-url http://10.3.4.182/arm-embedded/git-repo.git
将git仓库里的repo更新到/usr/bin下。如下:
[ ! -f /usr/bin/repo ] && ln -s `pwd`/git-repo/repo /usr/bin/repo
输入 repo version 如果正常返回,则repo不存在问题
cd /root/work2/git git init --bare test1.git git init --bare test2.git git init --bare test3.git git clone /root/work2/git/test1.git git clone /root/work2/git/test2.git git clone /root/work2/git/test3.git cd test1 && echo "hello world" > Readme && git add . && git commit -m "first commit" && git push && cd - cd test2 && echo "hello world" > Readme && git add . && git commit -m "first commit" && git push && cd - cd test3 && echo "hello world" > Readme && git add . && git commit -m "first commit" && git push && cd -
如果本身就有仓库,就无需创建,直接用即可。这里仅做测试验证
因为测试使用的服务器,为了ssh免密处理,这里需要把公钥拷过去
ssh-copy-id root@172.25.130.31
repo并不是在所有环境都能正常运行,它需要满足python到3.7及以上。
所以如果repo运行异常,则需要更新系统python到3.7及以上
git init --bare manifests.git git clone /root/work2/git/manifests.git vim manifests.git <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote fetch="ssh://root@172.25.130.31/root/work2/git" name="origin"/> <default remote="origin" revision="master" sync-j="4"/> <project name="test1" path="test1"/> <project name="test2" path="test2"/> <project name="test3" path="test3"/> </manifest> git add . && git commit -m "first commit" && git push
这里通过编写xml,设置远端的git仓库为root@172.25.130.31/root/work2/git, 远端的分支名字为origin,默认的remote为origin,版本分支为master,一共三个工程,分别为test1 test2 test3,并在本地创建同样的目录名字。
这样即可编写一个最简单的manifests.xml。后续可以使用这个xml来管理整个git仓库
repo init -u root@172.25.130.31:/root/work2/git/manifests.git repo sync
此时可以看到三个仓库被正常的拉取。
[root@localhost 3]# ls test1 test2 test3
在repo不断更新的过程中,可以生成快照,实际上就是生成一个xml文件,它保持了当时的repo状态,可供其他人使用。
这个类似于git tag。当需要整体出一个版本的时候,可以直接生成快照。
例如:
repo manifest -r -o tag_v1.0.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote fetch="ssh://root@172.25.130.31/root/work2/git" name="origin"/> <default remote="origin" revision="master" sync-j="4"/> <project dest-branch="master" name="test1" revision="831a146ccf46fe060c74f15354e9d68c3e0afbcb" upstream="master"/> <project dest-branch="master" name="test2" revision="829b53cce4538d5ae5919bc42bea7254bc1dcd9b" upstream="master"/> <project dest-branch="master" name="test3" revision="750f8d272da0b85a7bb7c42427fe9f0c72d416be" upstream="master"/> </manifest>
这里就比较显而易见了,快照保持了每个分支的分支信息,commit信息和上游信息
查看分支状态
repo status
为某个分支创建新的branch
repo start bug_1.2 test1
上面这个命令等同于
git checkout -b bug_1.4
查看分支信息
repo branch
查看所有分支的diff
repo diff
其他就不列举了。因为repo实际就是git命令的封装,有时间可能在仓库里面直接运行git会更加方便。
默认的xml头
<?xml version="1.0" encoding="UTF-8"?>
顶层manifest元素
<manifest> </manifest>
<remote />
name 这里的name是git remote的那个远程名字,默认是origin。如果是git的remote是其他的,这里填写对应即可 fetch 这里是git的地址,如果是ssh可以是:ssh://root@172.25.130.31/root/work2/git 如果是http或者git,就是github/gitlab上的地址 pushurl 这里是push的地址,当指定该属性的时候,这个值会和<project>标签中的name属性拼成完整的push url路径,这样当我们使用git push命令的时候,就会使用该url。如果不指定该属性,则pushurl和fetch一样。 revision 这里是默认的git branch名字。可以是master或者其他
<default />
remote 这里是remote设置的名字,代表repo拉的分支默认使用哪个remote上的 revision 当一个<project>不指定revision的时候使用该值 dest-branch 默认创建的本地分支,如果不指定,就是revision默认创建的分支 sync-j repo sync的并行数目 sync-c 如果设置为true,则只同步指定的分支(revision 属性指定),而不是所有的ref内容 sync-s 如果设置为true,则会同步git的子项目 sync-tags
<project />
name: 这里是工程名也就是哪个仓库 ${remote_fetch}/${project_name}.git path: 显式声明的存放文件路径 remote: 这里指定的远程分支名字 revision: 这里指定需要获取的git提交点,可以是master, refs/heads/master, tag或者SHA-1值。如果不设置的话,默认下载当前project,当前分支上的最新代码。 upstream: 在哪个git分支可以找到一个SHA1。用于同步revision锁定的manifest(-c 模式)。该模式可以避免同步整个ref空间。
xml可以直接include子xml。通过如下方式
<manifest> <include name="default.xml" /> </manifest>
<project name="test1" path="test1"> <linkfile dest="Readme" src="Readme"/> <copyfile dest="Readme.md1" src="Readme.md"/> </project>
在project下面设置可以设置软连接和拷贝。实际上等效于如下
ln -s test1/Readme Readme cp test1/Readme.md Readme.md1
https://gerrit-googlesource.proxy.ustclug.org/git-repo
https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.md
在调试linux时,经常需要翻阅串口的信息,而串口通常需要串口线引出来,而整机一般情况下串口是封闭的。为了调试更好的看的串口信息,可以借助netconsole功能。
CONFIG_NETCONSOLE=y
这里默认对serverip进行ping操作,如果serverip在线,则自动开始netconsole,否则正常流程boot
setenv serverip 172.25.80.123 setenv ipaddr 172.25.80.124 setenv if_netconsole 'ping $serverip' setenv start_netconsole 'setenv ncip $serverip; setenv stdin nc; setenv stdout nc; setenv stderr nc;' run if_netconsole start_netconsole
netconsole命令来自uboot源码tools/netconsole。
./netconsole 172.25.80.124 6666
在某些情况下,如果linux内核破坏,uboot正常。系统无法开机,并且uboot的下载按键无法使用时。可以通过默认的服务器ip地址来对uboot进行命令行调试。例如download命令进入下载模式。
但是在一般情况下,只要保证uboot的下载按键正常时,此方法并无大用。仅留作备选方案之一考虑
CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y
编译的netconsole.ko,在需要使用的时候,有两种方式来使用
insmod netconsole.ko netconsole=6666@172.25.80.125/eth0,6666@172.25.80.123/00:0c:29:d7:44:0b
这里netconsole参数需要带如下几个信息
netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr] where + if present, enable extended console support src-port source for UDP packets (defaults to 6665) src-ip source IP to use (interface address) dev network interface (eth0) tgt-port port for logging agent (6666) tgt-ip IP address for logging agent tgt-macaddr ethernet MAC address for logging agent (broadcast)
通俗点也就是
端口地址@本机IP地址/网卡名称,端口地址@服务器IP地址/MAC地址 这里 本地IP为172.25.80.125,网卡名称为eth0,默认使用端口6666,远程IP为172.25.80.123,网卡mac地址为00:0c:29:d7:44:0b,默认使用端口为6666
cd /sys/kernel/config/netconsole/ mkdir target echo 6666 > local_port echo 172.25.80.125 > local_ip echo eth0 > dev_name echo 6666 > remote_port echo 172.25.80.123 > remote_ip echo 00:0c:29:d7:44:0b > remote_mac echo 1 > enabled
卸载
echo 0 > enabled rmdir target rmmod netconsole
默认内核的cmdline没有指定loglevel的情况下,可以通过dmesg手动调试日志
dmesg -n 8
这样在netconsole就能看的内核日志信息了
在设备上,如果不想登录服务器地址,可以通过arp查看mac
ping -c 1 172.25.80.123 ; /sbin/arp -n | grep 172.25.80.123
nc -lup 6666
内核打开netconsole的作用比较明显,内核本身的/var/log/kern.log带缓冲,信息不及时。串口接出来不方便。但是需要实时的查看内核日志的时候,可以使用这个办法
https://github.com/u-boot/u-boot/blob/master/doc/usage/netconsole.rst https://www.kernel.org/doc/html/latest/networking/netconsole.html