diff --git a/doc/tutorials/ospp-kernelci/device-type/Lpi4A.jinja2 b/doc/tutorials/ospp-kernelci/device-type/Lpi4A.jinja2 new file mode 100755 index 0000000000000000000000000000000000000000..de2db002b1fdc3d541fd8447a91d79aa58e9fe8f --- /dev/null +++ b/doc/tutorials/ospp-kernelci/device-type/Lpi4A.jinja2 @@ -0,0 +1,26 @@ +{% extends 'base-uboot.jinja2' %} + +{% set uboot_mkimage_arch = 'riscv' %} +{% set console_device = console_device|default('ttyS0') %} +{% set baud_rate = baud_rate|default(115200) %} + +{% set booti_kernel_addr = '0x00200000' %} +{% set booti_dtb_addr = '0x03800000' %} +{% set booti_ramdisk_addr = '0x06000000' %} + +{% set uboot_initrd_high = '0xffffffffffffffff' %} +{% set uboot_fdt_high = '0xffffffffffffffff' %} + +{% set boot_character_delay = 100 %} + +{% set shutdown_message = 'The system will reboot now!' %} +{% set bootloader_prompt = bootloader_prompt|default('Light LPI4A#') %} + +{% set uboot_tftp_commands=[ + "tftp 0x0 mine/final/dtb/fw_dynamic.bin", + "bootslave", + "tftp {KERNEL_ADDR} {KERNEL}", + "setenv initrd_size ${filesize}", + "tftp {DTB_ADDR} {DTB}"] +-%} + diff --git "a/doc/tutorials/ospp-kernelci/doc/LAVA-LAB\347\232\204\346\220\255\345\273\272.md" "b/doc/tutorials/ospp-kernelci/doc/LAVA-LAB\347\232\204\346\220\255\345\273\272.md" new file mode 100644 index 0000000000000000000000000000000000000000..4c65826d958b75aafc5d86db71e0519ff5181be3 --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/LAVA-LAB\347\232\204\346\220\255\345\273\272.md" @@ -0,0 +1,294 @@ +# 部署 LAVA LAB + +## 直接部署 (本文档不推荐) + +### 1. 系统要求 + +确保你的 Ubuntu 系统满足以下要求: + +- Ubuntu 20.04 或更高版本 +- Python 3.6+ +- PostgreSQL +- RabbitMQ +- Git + +### 2. 安装依赖 + +首先,更新系统并安装必要的依赖项: + +```bash +sudo apt update +sudo apt upgrade +sudo apt install -y python3 python3-pip python3-dev postgresql postgresql-contrib rabbitmq-server git +``` + +### 3. 创建 LAVA 数据库 + +创建一个用于 LAVA 的 PostgreSQL 数据库和用户: + +```bash +sudo -u postgres psql +CREATE DATABASE lava; +CREATE USER lava WITH PASSWORD 'your_password'; +GRANT ALL PRIVILEGES ON DATABASE lava TO lava; +``` + +### 4. 克隆 LAVA 源代码 + +使用 Git 克隆 LAVA 的源码: + +```bash +git clone https://github.com/lava-lab/lava.git +cd lava +``` + +### 5. 安装 Python 依赖 + +在 LAVA 目录中,使用 pip 安装所需的 Python 依赖: + +```bash +pip3 install -r requirements.txt +``` + +### 6. 配置 LAVA + +复制示例配置文件并进行编辑: + +```bash +cp lava/settings.py.example lava/settings.py +``` + +根据需要编辑`lava/settings.py`,特别是数据库连接部分,确保填写正确的数据库名称和用户信息。 + +### 7. 迁移数据库 + +执行数据库迁移以创建相应的表: + +```bash +python3 manage.py migrate +``` + +### 8. 启动服务 + +使用以下命令启动 LAVA 服务: + +```bash +python3 manage.py runserver 0.0.0.0:8000 +``` + +### 9. 访问 LAVA + +在浏览器中访问 `http://你的服务器IP:8000`,你应该可以看到LAVA的界面。 + +### 10. 配置 RabbitMQ + +确保 RabbitMQ 正在运行,并且可以通过以下命令查看状态: + +```bash +sudo systemctl status rabbitmq-server +``` + +你可以使用 RabbitMQ 管理界面进行进一步配置,默认情况下,管理界面可以通过`http://localhost:15672`访问。 + + + +**可以看到比较繁琐,所以lava提供了也可以通过 docker compose 来快速的构建开发环境,接下来我们着重于这方面** + + + +## 使用 docker 部署 + +### 1.安装 docker 环境 + +由于使用 docker compose 部署 LAVA ,所以需要安装 docker 和 docker compose , 安装方法可以参照 [Ubuntu | Docker Docs](https://docs.docker.com/engine/install/ubuntu/) + +由于我使用的是 WSL 2 这里我本人遇到的问题有 + +```shell +sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc +``` + +无法正常获取资源,所以我使用windows获取资源再传到我的 WSL2 对应位置中 + +如果在安装过程中出现了无法获取docker镜像的情况,可以考虑为机器上代理 + +如果无法正常拉取镜像,有可能是我们连接官网的速度太慢,建议可以为 docker 也配置镜像源(或者说可能存在 daemon.json 不存在的问题 https://www.converts.cn/article/7097541.html) + +方法为 + +```shell +vim /etc/docker/daemon.json +``` + +```shell +{ + "registry-mirrors": [ + "https://dockerhub.icu", //疑似不行了 + "https://docker.chenby.cn", + "https://docker.1panel.live", + "https://docker.aWSL9527.cn", + "https://docker.anyhub.us.kg", + "https://dhub.kubesre.xyz" + ] +} +``` + +这里的几个源 本人用着没什么问题,不过也存在有些镜像源会对拉取次数少的镜像有限制的情况,如果是自己配置过镜像源的同学可以留意下这一点。 + +还有记得换源后重启 docker + +```shell +sudo systemctl restart docker +``` + +----- + +**将当前用户添加到docker组内(可选)** + +为了方便不用 sudo 执行 docker 命令,可以将当前用户添加到docker组内 + +``` +sudo groupadd docker //添加docker用户组 +sudo usermod -a -G docker $(whoami) //将当前用户添加到docker组内 +sudo systemctl restart docker //重启docker service +``` + +执行完以上命令,退出当前终端操作界面再次进入,就可以不用 sudo 执行 docker 命令了 + +----- + +### 2.获取 LAVA 源码 + +用 docker compose 部署LAVA, 从 https://github.com/kernelci/lava-docker 获取源码 + +建议 fork 下来因为还要对源码进行一些更改 + +```shell +git clone https://github.com/kernelci/lava-docker.git +cd lava-docker +``` + +如果是第一次使用 lava-docker 的同学,我还是想要更完备的讲解下项目大概的内容,如果有需要的话可以查看 [lava-docker细节解释](./lava-docker细节解释.md) + +直接进入主题 + +### 3.修改配置 + +#### 修改 lavalab-gen.py + +- 修改 master 对应149行内容 + + ```python + dockcomp = {} + dockcomp["version"] = "2.4" + dockcomp["services"] = {} + dockcomposeymlpath = "output/%s/docker-compose.yml" % host + dockcomp["services"][name] = {} + dockcomp["services"][name]["hostname"] = name + dockcomp["services"][name]["ports"] = [ listen_address + ":" + str(webinterface_port) + ":80"] + dockcomp["services"][name]["volumes"] = [ "/home/feifei/ospp/2024ospp-large-files/ubuntu/boot:/boot", "/home/feifei/ospp/2024ospp-large-files/ubuntu/modules:/lib/modules" ,"/home/feifei/ospp/2024ospp/device-type/LicheePi4A_4.jinja2:/usr/share/lava-server/device-types/LicheePi4A_4.jinja2" ] #映射一些组件和 lichepi4a 的 device-type + dockcomp["services"][name]["build"] = {} + dockcomp["services"][name]["build"]["context"] = name + if "build_args" in master: + dockcomp["services"][name]["build"]["args"] = master['build_args'] + dockcomp["services"][name]["restart"] = "always" #添加开机自动运行参数 + ``` + +- 修改 slave 对应458行内容 + + ```python + dockcomp["services"][name] = {} + dockcomp["services"][name]["hostname"] = name + dockcomp["services"][name]["dns_search"] = "" + dockcomp["services"][name]["ports"] = [] + dockcomp["services"][name]["volumes"] = [ "/home/feifei/ospp/2024ospp-large-files/ubuntu/boot:/boot", "/home/feifei/ospp/2024ospp-large-files/ubuntu/modules:/lib/modules", + "/home/feifei/ospp/2024ospp-large-files:/home/2024ospp-large-files" ] #映射一些组件 这里包括启动需要的rooft 等文件,如果后续 job 中没有使用inline的资源便不用映射 + dockcomp["services"][name]["environment"] = {} + dockcomp["services"][name]["build"] = {} + dockcomp["services"][name]["build"]["context"] = name + if "build_args" in slave: + dockcomp["services"][name]["build"]["args"] = slave['build_args'] + dockcomp["services"][name]["restart"] = "always" #tip + ``` + +#### 创建 board.yaml + +```yaml +--- +masters: + - name: master + host: local + webinterface_port: 8000 + allowed_hosts: ['*'] + users: + - name: admin + token: adminlavatoken + password: v + superuser: true + staff: true + tokens: + - username: admin + token: dfjdfkfkdjfkdsjfslforci + description: no description +slaves: + - name: lab-slave-1 + host: local + remote_master: master + remote_user: admin + dispatcher_ip: 192.168.0.158 #这里不能用本地环回地址 因为与后续 bootloader 相关 + use_tftp: True + use_nfs: True + host_healthcheck: false + +boards: + - name: qemu-test + type: qemu + slave: lab-slave-1 + - name: Lpi4A + type: LicheePi4A_4 + slave: lab-slave-1 + connection_command: telnet 192.168.137.1 20000 //20000是ser2net配置的串口/dev/ttyUSB1对应的端口 也就是对应的 licheepi4a + #pdu_generic: ////远程控制电源的命令 这里是只用串口的 + #(echo "OFF"; sleep 1; echo "ON") | telnet 192.168.1.100 20001 + #(echo "ON") | telnet 192.168.1.100 20001 + #(echo "OFF") | telnet 192.168.1.100 20001 + uart: + idvendor: 0x0403 + idproduct: 0x6010 + devpath: "1" +``` + +配置完毕 + +### 4.创建 docker 容器 + +```shell +./lavalab-gen.py //生成部署需要的文件, 存放在 output/local/目录下 +cd output/local +docker compose build //生成 lava master 和 slave 的 docker image +docker compose up -d //运行 lava master 和 slave docker 容器 +``` + +### 5.使用 lava web + +可以使用 firefox edge chrome 等浏览器 + +如果你想我一样是 WSL 2 又不想做 端口映射的话 可以简单粗暴的在 WSL 2 里下载 firefox 使用,不过我这里会有一些细小的bug,不太影响使用,比如 lava 以及 Jenkins 提供的一些 预选项 无法用鼠标点击 需要使用就键盘选择。 + +在命令行执行以下命令进入浏览器 +```shell +firefox & +``` + +在浏览器中输入 http://127.0.0.1:8000 进入 lava web 界面,8000是 boards.yaml 中设置的 webinterface_port + +![lava-1](img/lava大概/lava-1.png)点击右上角的 **Sign in** 进行 admin 的登陆,在 **board.yaml** 否则无法提交 job + +至此 LAVA LAB 的基本环境已经搭建完毕 + +### 6.安装qemu + +```shell +sudo apt install qemu-system-misc +``` + diff --git a/doc/tutorials/ospp-kernelci/doc/README.md b/doc/tutorials/ospp-kernelci/doc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1151fb1ba033ffb09cd5d570b124968d96a73ba4 --- /dev/null +++ b/doc/tutorials/ospp-kernelci/doc/README.md @@ -0,0 +1,84 @@ +# 板块 + +## 需要准备的东西 - 所有板块 + +1. 服务器设备:一台主机,系统为 linux x86 (发行版为 debian 或 ubuntu ,似乎也可以使用 centos。 LAVA官方推荐使用debian),由于我的条件有限 这里使用的是 windows 11 下的 WSL2-Ubuntu-22.04 测试后也可以正常进行 LAVA 的搭建,不过需要额外注意一些东西,后文会详细说明 +2. 被测试的设备:一块开发板 ,这里由于 ospp 的要求,我使用的是 Licheepi 4a 8g-32g , 当然也可以使用其他开发板。 +3. 电源控制设备:esp8266 或是其他带有 wifi 模块的开发板 ,不通过网络也可以完成,只不过要挨个管理串口设备,后文会提到 +4. 硬件设备:若干杜邦线 ,电源 ,继电器。 + +# 章节 + +1. [搭建基础的开发环境](./搭建基础的开发环境.md) + - 直接使用 ubuntu + - windows 使用 WSL 2 或 VMware +2. [LAVA-LAB的搭建](./LAVA-LAB的搭建.md) + - 直接搭建 + - **通过 lava - docker来构建** +3. [已提供的设备类型-qemu](./已提供的设备类型-qemu.md) + - [lava-docker细节解释 ](./lava-docker细节解释.md) +4. [未提供的设备类型-自定义设备类型-Licheepi 4a](./未提供的设备类型-自定义设备类型-Lip4a.md) +5. [电源控制](./电源控制.md) + - **使用mqtt + esp8266** + - 使用其他开发板 + 串口 +6. [配置jenkins.md](./配置jenkins.md) +7. [编写job和testcase](./编写job和testcase.md) + +### 可能对你有些帮助 + +在处理 lava 时可能会需要重复的构建 docker 镜像,手动很麻烦,这里我给出几个简单的清理环境的脚本 + +导出所有容器 + +```shell +#!/bin/bash + +# 创建一个目录来保存导出的容器 +mkdir -p ~/docker_backups + +# 获取所有容器的 ID +container_ids=$(docker ps -aq) + +# 导出每个容器 +for id in $container_ids; do + container_name=$(docker inspect --format='{{.Name}}' $id | cut -c2-) # 去掉前面的斜杠 + docker export $id -o ~/docker_backups/$container_name.tar + echo "导出容器 $container_name ($id) 到 ~/docker_backups/$container_name.tar" +done +``` + +导出所有镜像 + +```shell +#!/bin/bash + +# 创建一个目录来保存导出的镜像 +mkdir -p ~/docker_image_backups + +# 获取所有镜像的名称 +image_names=$(docker images -q) + +# 导出每个镜像 +for image in $image_names; do + image_name=$(docker inspect --format='{{.RepoTags}}' $image | tr -d '[],') + docker save $image -o ~/docker_image_backups/$image_name.tar + echo "导出镜像 $image_name 到 ~/docker_image_backups/$image_name.tar" +done + +``` + +删除所有 docker 镜像和容器,你可以修改下 改成只删除 lava 相关的,我这里是**全部删除** + +```shell +#!/bin/bash + +# 停止并删除所有容器 +docker stop $(docker ps -aq) +docker rm $(docker ps -aq) + +# 删除所有镜像 +docker rmi $(docker images -q) + +echo "所有容器和镜像已删除。" + +``` diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins1.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins1.png new file mode 100644 index 0000000000000000000000000000000000000000..78ed2204ed7906ab038736d803d5c8e0da5f54af Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins1.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins10.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins10.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd4268df709e1def93919c9de8c221e83378e9e Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins10.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins11.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins11.png new file mode 100644 index 0000000000000000000000000000000000000000..2a78f7c5ae1aa4a77e844c716db1171ff14dadaf Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins11.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins12.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins12.png new file mode 100644 index 0000000000000000000000000000000000000000..e148a5380afa8601eb115f6573b8ae408a441df0 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins12.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins13.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins13.png new file mode 100644 index 0000000000000000000000000000000000000000..d24eac32d1e3f4d676bb47a273565e4cc4e4dbb0 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins13.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins14.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins14.png new file mode 100644 index 0000000000000000000000000000000000000000..d16182fba114de22eb514164cf0b10072885706e Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins14.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins15.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins15.png new file mode 100644 index 0000000000000000000000000000000000000000..6c364b17b0b74f966aa652cf6ff9ca9803d3103f Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins15.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins16.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins16.png new file mode 100644 index 0000000000000000000000000000000000000000..fa45d70d80944aa98fb36cef3628fa68eb85d051 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins16.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins17.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins17.png new file mode 100644 index 0000000000000000000000000000000000000000..e302f2149f8541d265a42c3367561ba842b99e7c Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins17.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins18.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins18.png new file mode 100644 index 0000000000000000000000000000000000000000..960011f01df34ea2283db377c3ae56eaa5805ff5 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins18.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins19.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins19.png new file mode 100644 index 0000000000000000000000000000000000000000..0c491e0cc7d801c886f438fa7bab09453d4860fd Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins19.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins2.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins2.png new file mode 100644 index 0000000000000000000000000000000000000000..cc467dead94bff2fced468603863673855a2ec10 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins2.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins20.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins20.png new file mode 100644 index 0000000000000000000000000000000000000000..2a8084ef324e32e2a3f39d566e1797bae0ba86fb Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins20.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins3.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins3.png new file mode 100644 index 0000000000000000000000000000000000000000..1a78bc8565cec1bce4340f8c0582b049924f439f Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins3.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins4.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins4.png new file mode 100644 index 0000000000000000000000000000000000000000..c886855392bfde9ce6bade38ff7afc2080a633c9 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins4.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins5.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins5.png new file mode 100644 index 0000000000000000000000000000000000000000..455d48a06a852311daf88fa456eb9485bfa365db Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins5.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins6.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins6.png new file mode 100644 index 0000000000000000000000000000000000000000..b67635667b3827a39410e9f7cb0fa3a403cc180d Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins6.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins7.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins7.png new file mode 100644 index 0000000000000000000000000000000000000000..f4a24b8caae49319225f2c80b6ad20e5a069c49a Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins7.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins8.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins8.png new file mode 100644 index 0000000000000000000000000000000000000000..f55f1f85f7c20a11204592e375f0694da2f1abd5 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins8.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins9.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins9.png new file mode 100644 index 0000000000000000000000000000000000000000..035b968412f2d8422fe819a6464e9f8804131f88 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkins9.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew1.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew1.png new file mode 100644 index 0000000000000000000000000000000000000000..6e44b16d1731c249a5f1ebfc42082f23e44b44c1 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew1.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew10.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew10.png new file mode 100644 index 0000000000000000000000000000000000000000..6a08422f89238f9333ba6b80c483b06c8c8ce8c9 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew10.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew11.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew11.png new file mode 100644 index 0000000000000000000000000000000000000000..a4c6204fc6fbf3ff6fcf67fd1ca246bcaa887301 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew11.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew12.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew12.png new file mode 100644 index 0000000000000000000000000000000000000000..e9fb02c473fe2c59b6258bb1762e38f0dd32b24e Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew12.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew13.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew13.png new file mode 100644 index 0000000000000000000000000000000000000000..f18917a76ffc6723662d855ade36bfd0a9dbc885 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew13.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew14.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew14.png new file mode 100644 index 0000000000000000000000000000000000000000..be407aeff6800387cb229900305d3e3d5702294d Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew14.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew15.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew15.png new file mode 100644 index 0000000000000000000000000000000000000000..cd99a70870f2f025f8c5de60b222e1693f92443e Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew15.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew2.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew2.png new file mode 100644 index 0000000000000000000000000000000000000000..60e138c06bcaa56bb27ce7245b5d7c78aa651094 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew2.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew3.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew3.png new file mode 100644 index 0000000000000000000000000000000000000000..832301af808c2dfe81bf5fa4836f3439bdfa8ea1 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew3.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew4.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew4.png new file mode 100644 index 0000000000000000000000000000000000000000..05bfaf1b6e8ba09d9ca59c5619487964be1a99c1 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew4.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew5.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew5.png new file mode 100644 index 0000000000000000000000000000000000000000..5a697f2aa279394b6fb9d6db2397d214e9df0c5b Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew5.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew6.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew6.png new file mode 100644 index 0000000000000000000000000000000000000000..4c43bb0e8f2609eb733660a352e712d26d865d7e Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew6.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew7.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew7.png new file mode 100644 index 0000000000000000000000000000000000000000..6b54c2be6269783fdd85907d4bc3d3883d68c99a Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew7.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew8.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew8.png new file mode 100644 index 0000000000000000000000000000000000000000..d835b5e57d93b7c4f20e93682591778db61535bc Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew8.png differ diff --git a/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew9.png b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew9.png new file mode 100644 index 0000000000000000000000000000000000000000..45ba16312fa4356858529d141cbb778205915919 Binary files /dev/null and b/doc/tutorials/ospp-kernelci/doc/img/jenkins/jenkinsnew9.png differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/job\345\222\214testcase/job\345\222\214testcase1.png" "b/doc/tutorials/ospp-kernelci/doc/img/job\345\222\214testcase/job\345\222\214testcase1.png" new file mode 100644 index 0000000000000000000000000000000000000000..c62df1b98f52930e198bcc5770b6220d8017d49a Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/job\345\222\214testcase/job\345\222\214testcase1.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-1.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..7b99474368439aec453f9035ee6fdc642b3a35a2 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-1.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-2.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..de8c4acd294acfd00c6d4ca66acab78e3860ebc7 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-2.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-3.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..5c65eef1ab1130c47867f13d123c5ed437b0e809 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-3.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-4.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-4.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb72a0e807abdcbda328b39583a4bfb232ec27d3 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-4.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-5.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-5.png" new file mode 100644 index 0000000000000000000000000000000000000000..2b02c315faadcafe66e7dc15097ef438338d5f3e Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-5.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-6.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-6.png" new file mode 100644 index 0000000000000000000000000000000000000000..d6b1b6b6a012155b58a305270e74659c02dd39a3 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\345\244\247\346\246\202/lava-6.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/1.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/1.png" new file mode 100644 index 0000000000000000000000000000000000000000..bccd2511e77f11bda38986605cab71fdc9e7b5e8 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/1.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/2.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/2.png" new file mode 100644 index 0000000000000000000000000000000000000000..9cd569f55f88420b7371d9e4311c6829736abee8 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/2.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/3.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/3.png" new file mode 100644 index 0000000000000000000000000000000000000000..0f4b158a0ea9f923ba07a3f90eb036742804ae95 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/3.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/4.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/4.png" new file mode 100644 index 0000000000000000000000000000000000000000..d1d4fe11205e863ba1a492c933665347ffcaa85d Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/4.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/5.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/5.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd0ef0b623322146a0f1ae18eb3e5910a37a3738 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/5.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_docker_1.drawio.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_docker_1.drawio.png" new file mode 100644 index 0000000000000000000000000000000000000000..b16fef2d0ffe94afd594406e829d391cc3405301 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_docker_1.drawio.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_docker_2.drawio.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_docker_2.drawio.png" new file mode 100644 index 0000000000000000000000000000000000000000..45961f64f5cb54d7d4a0b01e78f0258cb35ed740 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_docker_2.drawio.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_status.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_status.png" new file mode 100644 index 0000000000000000000000000000000000000000..8f6dd842d7509035d1c70a74e3624e98f790dd9c Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_status.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_work.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_work.png" new file mode 100644 index 0000000000000000000000000000000000000000..d160f0df608f38204e98e488fd6876e26e539c54 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/lava_work.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/onlyqemu.png" "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/onlyqemu.png" new file mode 100644 index 0000000000000000000000000000000000000000..16074ad4bf376142e6e6f8f8d31d7f2dad2c79d3 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/lava\350\257\246\347\273\206/onlyqemu.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/all.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/all.png" new file mode 100644 index 0000000000000000000000000000000000000000..5b169e615e3fe94b029b36162ac59d10d9a9c066 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/all.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/kselftest.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/kselftest.png" new file mode 100644 index 0000000000000000000000000000000000000000..57eecfae9c05a334855a09854df4dc542ee3d8fc Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/kselftest.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/kselftest2.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/kselftest2.png" new file mode 100644 index 0000000000000000000000000000000000000000..659bd2f21976e0be2e74118c43cf0baae807cdb0 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/kselftest2.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest.png" new file mode 100644 index 0000000000000000000000000000000000000000..f39cd73242c68a1642e5c8bd1d088a6c060d0241 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest2.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest2.png" new file mode 100644 index 0000000000000000000000000000000000000000..401d4bedd58178acf7ebd229f940e577bba6b134 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest2.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest3.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest3.png" new file mode 100644 index 0000000000000000000000000000000000000000..35668d4fdc01db72b5f0a941d2adf3ad98addfa1 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/lpi4a/ltptest3.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/all.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/all.png" new file mode 100644 index 0000000000000000000000000000000000000000..cd28528948d06a74cd260ae938f07b9206225cb4 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/all.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/kselftest.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/kselftest.png" new file mode 100644 index 0000000000000000000000000000000000000000..154795cbea1db5e7b2f49cf295d9b67abd2e06cf Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/kselftest.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/kselftest2.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/kselftest2.png" new file mode 100644 index 0000000000000000000000000000000000000000..9bc6c7fe55ce4487efebd321c568a7bc3d4ccfaa Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/kselftest2.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/ltp2.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/ltp2.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0e4dc3af71ea142ea135d434e7d75e704116996 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/ltp2.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/ltptest.png" "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/ltptest.png" new file mode 100644 index 0000000000000000000000000000000000000000..71caf7920c716c4b522b7bb4a9e33739e5f5bed8 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\346\210\220\346\236\234/qemu/ltptest.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\347\241\254\344\273\266/licheepi1.png" "b/doc/tutorials/ospp-kernelci/doc/img/\347\241\254\344\273\266/licheepi1.png" new file mode 100644 index 0000000000000000000000000000000000000000..b6e3fca62e3fb14635d65bfb10cf0e6c3e252e27 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\347\241\254\344\273\266/licheepi1.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\347\241\254\344\273\266/licheepi2.png" "b/doc/tutorials/ospp-kernelci/doc/img/\347\241\254\344\273\266/licheepi2.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cf5d3630ffd78b971429f652a877341bf4ae645 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\347\241\254\344\273\266/licheepi2.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/img/\351\205\215\347\275\256\345\237\272\346\234\254\347\216\257\345\242\203/\351\205\215\347\275\256\345\237\272\346\234\254\347\216\257\345\242\2031.png" "b/doc/tutorials/ospp-kernelci/doc/img/\351\205\215\347\275\256\345\237\272\346\234\254\347\216\257\345\242\203/\351\205\215\347\275\256\345\237\272\346\234\254\347\216\257\345\242\2031.png" new file mode 100644 index 0000000000000000000000000000000000000000..fbdb98ff0c09735a52431125ad26507ad09aea44 Binary files /dev/null and "b/doc/tutorials/ospp-kernelci/doc/img/\351\205\215\347\275\256\345\237\272\346\234\254\347\216\257\345\242\203/\351\205\215\347\275\256\345\237\272\346\234\254\347\216\257\345\242\2031.png" differ diff --git "a/doc/tutorials/ospp-kernelci/doc/lava-docker\347\273\206\350\212\202\350\247\243\351\207\212.md" "b/doc/tutorials/ospp-kernelci/doc/lava-docker\347\273\206\350\212\202\350\247\243\351\207\212.md" new file mode 100644 index 0000000000000000000000000000000000000000..90055bb780a26549482e9222b316cd217f2896bb --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/lava-docker\347\273\206\350\212\202\350\247\243\351\207\212.md" @@ -0,0 +1,414 @@ +## 总体介绍 + +首先可以参考官方文档 [LAVA 简介 — LAVA 2024.05 文档 (lavasoftware.org)](https://docs.lavasoftware.org/lava/index.html#) + +可能会有点难以理解 + +![lava_work](img/lava详细/lava_work.png) + +可以参考官方文档的这张图 + +通俗点说就是 LAVA 是一种测试框架,用来管理被测试设备,使用者需要根据这个测试框架的规则来开发测试套和测试用例,测试用例需要使用者根据自己的需求更改。 + +由 **master** 提供 web 界面 以及各种交互的接口,存储测试定义,测试结果等,**slave** 与被测试的设备直接连接,来控制被测试的机器。 + +大家可以在 [Index — LAVA 2024.05 documentation (lavasoftware.org)](https://docs.lavasoftware.org/lava/genindex.html) 找到很多信息,但是资料有些过多,并且有些已经很久没更新了,再加上其中提供的一些 url 已经失效了,可能会产生一些障碍 + +回到项目本身,由于我们使用 lava-docker ,本质上是在当前的机器上创建了 docker 容器,如何创建详见下文。 + +## lava-docker 基础介绍 + +### 解释源码以及运作方式 + +源码链接 https://github.com/kernelci/lava-docker.git + +![lava_docker_1.drawio](img/lava详细/lava_docker_1.drawio.png) + +使用 lavalab-gen.py 生成 master 以及 slave 的基础镜像 + +**源码由以下部分组成** + +1. boards.yaml + + - 根据自己的需要 编写 boards.yaml (原项目下存在一些 example) + + - 根据需要修改 lavalab-gen.py +2. healthcheck + + - 存储的是 healthcheck 的定义 由于 healthcheck 需要拉取 github 上的源码,由于国内的网络问题,可能需要为生成的 docker 像配置代理等 比较麻烦,可以在这里提前将 healthcheck 拉取的源码 替换为本地路径 /或是本地地址你 fork 到 gitee 上的克隆镜像仓库地址 +3. lava-master 和 lava-slave + - lava-master 和 lava-slave 分别用来创建 lava-master 和 lava-slave 容器镜像 + - 里面除了包含 Dockerfile 还有一些文件夹,用来存储一些基于自己需求的配置,应该是为了使项目不杂乱,比如把需要的一些组件放在这里,在修改 lavalab-gen.py 时指向这里,比较方便资源的管理。 +4. others + + - 并非不重要,只是在当前项目中没修改的部分 ,可以自行阅读源码 + - dhcpd:用来为网络中的设备分配 IP + - boards.yaml.example 或 board-ci.yaml 作为 boards.yaml 的例子 + +将一切修改完毕 就可以运行 lavalab-gen.py 此时会出现 **local/output** 文件夹 + +**output 文件夹由以下部分组成** + +1. master 文件夹 (由 boards.yaml 中的设置的内容决定文件夹名称 ) + + - 直接 copy 根目录中 lava-master 里面的内容 + - 根据 boards.yaml 中的内容生成的一些 user 或 token 信息 +2. lab-slave-1 文件夹 (由 boards.yaml 中的设置的内容决定文件夹名称 ) + + - 直接 copy 根目录中 lava-master 里面的内容 + - 根据 boards.yaml 中的内容生成的 一或多个 slave 容器 +3. deploy.sh + + - 用于管理和配置系统 Udev 规则以及启动 Docker 容器的 Shell 脚本 +4. docker-compose.yml + + - 根据 boards.yaml 中的内容生成,配置 容器的端口等设置,将主机文件映射到 docker 容器内部 + +### 运行 + +配置好 board.yaml 就可以顺利的 使用 docker 搭建 lava 了 + +```shell +./lavalab-gen.py //生成部署需要的文件, 存放在 output/local/目录下 +cd output/local +docker compose build //生成 lava master 和 slave 的 docker image +docker compose up -d //运行 lava master 和 slave docker 容器 +``` + +正常的话不做任何修改也是可以跑起来的,只需要编写好 board.yaml 这里给出一个简单例子 + +```yaml +--- +masters: + - name: master + host: local + webinterface_port: 8000 //web端口 + allowed_hosts: ['*'] + users: + - name: admin + token: adminlavatoken //token 与 kernel ci 或是 Jenkins 交互都要使用 + password: v + superuser: true + staff: true + tokens: + - username: admin + token: dfjdfkfkdjfkdsjfslforci + description: no description +slaves: + - name: lab-slave-1 + host: local + remote_master: master + remote_user: admin + dispatcher_ip: 127.0.0.1 + use_tftp: True + use_nfs: True + host_healthcheck: false +boards: + - name: qemu-test + type: qemu + slave: lab-slave-1 +``` + +在浏览器中输入 http://127.0.0.1:8000 进入 lava web 界面,8000是 boards.yaml 中设置的 webinterface_port + +lava web 端可以干很多事情(其实和使用 lava service 的子命令类似) + +提交 device-type ,job 更改 设备状态等 + +![1](img/lava详细/1.png) + +( lava 界面) + +由于此时的 **board.yaml** 中只配置了 一个 slave 和 board + +```yaml +slaves: + - name: lab-slave-1 + host: local + remote_master: master + remote_user: admin + dispatcher_ip: 127.0.0.1 + use_tftp: True + use_nfs: True + host_healthcheck: false +boards: + - name: qemu-test + type: qemu + slave: lab-slave-1 +``` + +![lava_status](img/lava详细/lava_status.png) + +查看 Status + +![onlyqemu](img/lava详细/onlyqemu.png) + +## 处理问题 + +此时的 online devices 应该是一个,而且由于 qemu 类型会自己执行 healthcheck ,所以目前应该有一个 running test job 便是 healthcheck + +### healthcheck + +上文也提到过,由于网络问题,有可能你的 healthcheck 过不去,过不去便会一直执行,导致无法处理其他job,所以要先解决 **healthcheck** 的问题 + +解决方案: + +1. 为 qemu对应的 slave 容器 配置代理等,直接解决网络问题 +2. 把 定义中的 https://github.com/BayLibre/lava-healthchecks-binary.git 替换为国内的镜像仓库 + +和我一样使用 WSL 2 的同学解决这些问题可能还会遇到一些报错,最后定位到是因为,WSL 2 中的 Ubuntu 是 Windows 特化版本的 Ubuntu ,虽然其内核版本满足了 healthcheck 的版本要求,但是其中的 引导目录`/boot`以及 模块目录`/lib/modules` 和 lava 的适配都有问题,我这里采用了最简单的方法,便是把 ubuntu-22.04 x86 对应的目录直接 copy 到 WSL 2 中,并在构建 docker 容器时 指向对应的目录,即 **修改 lavalab-gen.py** + +![4](img/lava详细/4.png) + +这里便是将 提供的 boot 映射为 master 的 boot ,modules 自然也是同理 ,这里陪着的是 master ,slave 在文件462行左右,配置方法都是一样的。 + +master 不这样更改也可以 因为 master 不需要做一些测试 ,目前使用起来没出现问题。 + +解决这些问题后,之后 WSL2 和实体机的体感应该是一致的 + +## 编写 job + +这里给出一个 qemu 的 example + +```yaml +# Your first LAVA JOB definition for an riscv_64 QEMU +device_type: qemu +job_name: qemu-oerv-24.03-smoke-test +timeouts: + job: + minutes: 30 + action: + minutes: 20 + connection: + minutes: 5 +priority: medium +visibility: public +# context allows specific values to be overridden or included +context: + # tell the qemu template which architecture is being tested + # the template uses that to ensure that qemu-system-riscv64 is executed. + arch: riscv64 + machine: virt + guestfs_interface: virtio + extra_options: + - -nographic -machine virt,pflash0=pflash0,pflash1=pflash1,acpi=off + - -smp 4 + - -m 8G + - -object memory-backend-ram,size=4G,id=ram1 + - -numa node,memdev=ram1 + - -object memory-backend-ram,size=4G,id=ram2 + - -numa node,memdev=ram2 + - -object rng-random,filename=/dev/urandom,id=rng0 + - -device virtio-vga + - -device virtio-rng-device,rng=rng0 + - -device virtio-blk-device,drive=hd0,bootindex=1 + - -device virtio-net-device,netdev=usernet + - -netdev user,id=usernet,hostfwd=tcp::12055-:22 + - -device qemu-xhci -usb -device usb-kbd -device usb-tablet +metadata: + # please change these fields when modifying this job for your own tests. + format: Lava-Test Test Definition 1.0 + name: qemu-oerv-24.03-test + description: "test for oerv qemu image" + version: "1.0" +# ACTION_BLOCK +actions: +# DEPLOY_BLOCK +- deploy: + timeout: + minutes: 20 + to: tmpfs + images: + kernel_1: + image_arg: -blockdev node-name=pflash0,driver=file,read-only=on,filename={kernel_1} + url: file:///home/2024ospp-large-files/qemu/RISCV_VIRT_CODE.fd + kernel_2: + image_arg: -blockdev node-name=pflash1,driver=file,filename={kernel_2} + url: file:///home/2024ospp-large-files/qemu/RISCV_VIRT_VARS.fd + rootfs: + image_arg: -drive file={rootfs},format=qcow2,id=hd0 + url: file:///home/2024ospp-large-files/qemu/openEuler-24.03-LTS-riscv64.qcow2.zst + compression: zstd +# BOOT_BLOCK +- boot: + timeout: + minutes: 20 + method: qemu + media: tmpfs + prompts: ["root@openeuler-riscv64"] + auto_login: + login_prompt: "localhost login:" + username: root + password_prompt: "Password:" + password: openEuler12#$ +# TEST_BLOCK +- test: + timeout: + minutes: 10 + definitions: + - repository: https://git.linaro.org/lava-team/lava-functional-tests.git + from: git + path: lava-test-shell/smoke-tests-basic.yaml + name: smoke-tests +``` + +这里使用的镜像是 官方仓库的镜像 [openEuler下载](https://www.openeuler.org/zh/download) + +值得注意的是 openEuler 不同版本 或是不同来源的 镜像 启动脚本可能不太相同,需要根据需要修改 job 的内容 + +根据你的 device 来处理 **TEST_BLOCK** 以上的内容 + +这里以 openEuler 24.03 做演示 + +这里用 yaml 启动部分的内容和官方提供的 start.vm 脚本做下对比 + +### DEPLOY_BLOCK + +![5](img/lava详细/5.png) + +左侧为 job ,右侧为 start_vm 脚本 + +字体有些小 但应该能看出来 实际上就是把启动脚本需要的参数 用 lava 需要的格式做出来 + +简单来说就是 不需要引用外部文件的 不需要动 放在 context 下`当然一些 define 如 $ssh_port 可以直接替换为 其对应的值或文本`, 需要处理的 比如 start_vm 中需要 引入 openEuler-24.03-LTS-riscv64.qcow2.zst 这个 rootfs + +则需要把对应语句移入 - deploy 的 image 下 + +编写大概是这样 + +```yaml +images: + roofts: #变量名对应下一句中的内容 + image_arg: -drive file={rootfs},format=qcow2,id=hd0 #对应上一句中的 roofts + url: file:///home/2024ospp-large-files/qemu/openEuler-24.03-LTS-riscv64.qcow2.zst #可以是本地资源,也可以是网络资源 + compression: zstd #提供的是什么格式的 rootfs +``` + +注意注意缩进 `file={rootfs}`中间不能有空格 + +### BOOT_BLOCK + +```yaml +# BOOT_BLOCK +- boot: + timeout: + minutes: 20 + method: qemu + media: tmpfs + prompts: ["root@openeuler-riscv64"] + auto_login: + login_prompt: "localhost login:" + username: root + password_prompt: "Password:" + password: openEuler12#$ +``` + +这里需要到实际的机器中查看其提供的信息,欧拉各版本的启动提示词并不相同 + +比如 24.03 LTS 是 `locolhost login:` 而 23.09 则是 `openeuler-riscv64 login:` + +我这里尝试过 字符串匹配 常出现bug,暂时就不统一了 有的区别只有 `e` 的大小写 + +这里是最重要的环节之一,可能会遇到非常多你意想不到的问题,之后我可能会更新 + +最后便是处理 + +### TEST_BLOCK + +```yaml +# TEST_BLOCK +- test: + timeout: + minutes: 10 + definitions: + - repository: https://git.linaro.org/lava-team/lava-functional-tests.git + from: git + path: lava-test-shell/smoke-tests-basic.yaml + name: smoke-tests +``` + +这里便是测试的相关内容,比如这个执行一个 smoke-test 来源则是 git 当然来源也可以是本地等,此时已经进入测试机环境了,你也可以直接编写测试脚本在这里运行。 + +## 测试的方法 + +我说的可能不清楚 可以查看 [Submit a job - LAVA](https://lava.readthedocs.io/en/latest/user/basic-tutorials/submit/) +### 1.首先是自己编写 + +可以查看 [Glossary of terms — LAVA 2024.05 documentation (lavasoftware.org)](https://docs.lavasoftware.org/lava/glossary.html#term-job-definition) + +```yaml + +# TEST_BLOCK +- test: + timeout: + minutes: 600 + definitions: + - repository: + metadata: + format: Lava-Test Test Definition 1.0 + name: kselftest-ptrace-test + run: + steps: + - yum install -y git make gcc flex bison clang + - df -h + - cd /root + - git clone https://gitee.com/feifei-fertilizer/riscv-kernel.git + - cd riscv-kerner.git + - git checkout OLK-6.6 + - make defconfig + - make -C tools/testing/selftests + - make -C tools/testing/selftests TARGETS=clone3 run_tests + from: inline + name: kselftest-inline + path: inline/kselftest.yaml +``` + +这是一个基于内核源码的 **kselftest** + +可以看到 + +### 2.基于test-definitions + +可以通过 clone [Linaro/test-definitions: Test definitions work with and without LAVA (github.com)](https://github.com/Linaro/test-definitions) 来直接使用其准备好的测试 + +根据描述官方文档描述 [test-definitions/docs/index.md 在 master ·Linaro/测试定义 (github.com)](https://github.com/Linaro/test-definitions/blob/master/docs/index.md) + +**测试套件可以在有和没有 [LAVA](http://lavasoftware.org/) 的情况下工作。以下两个 支持自动测试集。** + +- **`automated/linux/`** +- **`automated/android/`** + +我需要做的 ltp test 正位于 **`automated/linux/`** 中 + +```yaml +- test: + timeout: + minutes: 600 + definitions: + - repository: https://github.com/Linaro/test-definitions.git + from: git + path: automated/linux/ltp/ltp.yaml + parameters: + TST_CMDFILES: syscalls + SKIPFILE: skipfile-lkft.yaml + BOARD: qemu + BRANCH: master + ENVIRONMENT: production + TIMEOUT_MULTIPLIER: '30' + ROOT_PASSWD: openEuler12#$ + BUILD_FROM_TAR: true + LTP_VERSION: 20240524 + LTP_TMPDIR: /scratch + name: ltp-syscalls-tests +``` + +当然只要拉取 github 上面的代码总要先解决网络问题 + +----- + +ps:如果你使用串口连接硬件设备进行测试 还需要更改 docker-compose.yml 中的内容,我决定放在自定义设备那章节中 + + + +到这里我便演示了如何起一个最简单的测例,当然这比起真正的测试还有很多路要走. + diff --git "a/doc/tutorials/ospp-kernelci/doc/\345\267\262\346\217\220\344\276\233\347\232\204\350\256\276\345\244\207\347\261\273\345\236\213-qemu.md" "b/doc/tutorials/ospp-kernelci/doc/\345\267\262\346\217\220\344\276\233\347\232\204\350\256\276\345\244\207\347\261\273\345\236\213-qemu.md" new file mode 100644 index 0000000000000000000000000000000000000000..83082eba69a7714de23be613144ac530ce9e0163 --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/\345\267\262\346\217\220\344\276\233\347\232\204\350\256\276\345\244\207\347\261\273\345\236\213-qemu.md" @@ -0,0 +1,64 @@ +做完了前面的工作 + +如果你需要短时间测试你的 job 以及 测试用例 ,频繁的 healthcheck 会占用你的机器 + +## 修改 healthcheck 触发条件(可选) + +可以修改 healthcheck 的触发时间,可以 disable healthcheck + +![lava-2](img/lava大概/lava-2.png) + +点击 **device-type** + +![lava-3](img/lava大概/lava-3.png) + +这里可以看到设备的 healthcheck 状态 我这里已经把 qemu 的 自动触发关闭了 + +![lava-4](img/lava大概/lava-4.png) + +选择 **Disable health check for devices of this type** + +![lava-5](img/lava大概/lava-5.png) + + + + + +## 提交 job 及触发 + +![lava-6](img/lava大概/lava-6.png) + +回到主页直接点击 **Submit** 就会出现一个提交界面,提交你的 job 定义就好啦 + +查看 job 结果等这里都不再赘述了 + +在 [lava-docker细节解释 ](./lava-docker细节解释.md)中我解释了一个 基于 openEuler riscv 24.03 LTS 的 smoke 测试,可以参考下 + + + +## 处理 healthcheck 的网络问题 + +由于 healthcheck 的源码位于 github 上,在拉取时可能会遇到网络问题,这里我给出一种解决方案 + +可以在 构建 lava 容器前修改源码中 healthcheck 的 **Dockerfile** + +位于源码根目录的 healthcheck 文件夹下 + +```dockerfile +FROM bitnami/minideb:bullseye + +RUN apt-get update && apt-get -y install git +RUN git clone https://github.com/BayLibre/lava-healthchecks-binary.git #将这一行换成国内的镜像仓库即可 + +FROM nginx:mainline-alpine + +COPY port.conf /etc/nginx/conf.d/ + +COPY --from=0 /lava-healthchecks-binary/mainline /usr/share/nginx/html/mainline/ +COPY --from=0 lava-healthchecks-binary/images /usr/share/nginx/html/images/ +COPY --from=0 lava-healthchecks-binary/next /usr/share/nginx/html/next/ +COPY --from=0 lava-healthchecks-binary/stable /usr/share/nginx/html/stable/ +``` + +也可以为你的 dokcer 容器配置代理 + diff --git "a/doc/tutorials/ospp-kernelci/doc/\346\220\255\345\273\272\345\237\272\347\241\200\347\232\204\345\274\200\345\217\221\347\216\257\345\242\203.md" "b/doc/tutorials/ospp-kernelci/doc/\346\220\255\345\273\272\345\237\272\347\241\200\347\232\204\345\274\200\345\217\221\347\216\257\345\242\203.md" new file mode 100644 index 0000000000000000000000000000000000000000..534219c86b75ee6f726d8f393e5ee859dfc706d5 --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/\346\220\255\345\273\272\345\237\272\347\241\200\347\232\204\345\274\200\345\217\221\347\216\257\345\242\203.md" @@ -0,0 +1,103 @@ +**注 :这里是非常基础的主机环境搭建环节,相信大部分看到这里的同学都是会的,但是为了做到完整,我会在这里写上如何进行完整的环境搭建,如果你已经完成了可以跳过.不过如果你使用的是虚拟机环境,这里可能仍有一些你需要注意的地方** + +# 主机环境 + +## 实体机 + +推荐 + +使用 Ubuntu 22.04 ,不过众所周知 ,ubuntu官方源的软件版本较低,可能需要从源码拉下来安装。 + +## 虚拟机 + +不太推荐,因为涉及到设备连接等问题,虚拟机的虚拟串口都是基于软件实现的,不知道哪个环节出问题就要排查好久。 + +但本人因为身边只有这些设备不得已使用虚拟机 + +### WSL 2 + +可以查看 windows 的官方文档 [安装 WSL | Microsoft Learn](https://learn.microsoft.com/zh-cn/windows/WSL/install) + +也可以自己网络搜索各种博客等,嫌麻烦甚至可以直接去 Microsoft Store 直接下现成的 + +### VMware + +直接去 Ubuntu 官网下载 [Download Ubuntu Desktop | Ubuntu](https://ubuntu.com/download/desktop) 不过我下的时候提示资源失效,但是相信国人最擅长处理的就是资源失效以及网络问题了。 + + +### 解决虚拟机与外界的连接问题 + +由于后期 uboot tftp 需要开发板可以 ping 到部署 lava-slave 的机器,在该文档的情况下即主机 ip ,所以这个 ip 至少应该是局域网可 ping 的 + +虚拟机要注意的最大问题是,默认没有独立的外部可 ping 的 ip,可能是跟随主机 ip 或是只能由主机访问的 ip 。 + +这里给出解决方案 + +#### WSL 2 +WSL 这里给出的解决方案是使用 hyper-v ,家庭版的 windows 系统默认并没有这个功能,可以通过网上的一些教程来获取该功能 [Windows10/11家庭版开启Hyper-V虚拟机功能详解——保姆教程及闭坑指南](https://zhuanlan.zhihu.com/p/667571538) ,然后通过桥接获得我们期望的效果 [WSL2子系统如何设置桥接和静态ip(保姆级教程)](https://blog.csdn.net/m0_73779708/article/details/140301364) + +#### VMware + +VMware 则是在虚拟机配置中将网络适配器切换至桥接模式,当然如果你用 VMware 连接开发板也需要打开串行端口和 USB 控制器 + + + +![image-20240927090911118](img/配置基本环境/配置基本环境1.png) + + + +# 配置软件源 + +参考清华镜像[ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror](https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/) + +或是中科大,淘宝镜像源等 + + + +由于我后期重新搭建了环节搭建环境出现了软件源的问题 这里给出我的配置 + +```list +# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to +# newer versions of the distribution. +deb http://archive.ubuntu.com/ubuntu/ jammy main restricted +# deb-src http://archive.ubuntu.com/ubuntu/ jammy main restricted + +## Major bug fix updates produced after the final release of the +## distribution. +deb http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted +# deb-src http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted + +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu +## team. Also, please note that software in universe WILL NOT receive any +## review or updates from the Ubuntu security team. +deb http://archive.ubuntu.com/ubuntu/ jammy universe +# deb-src http://archive.ubuntu.com/ubuntu/ jammy universe +deb http://archive.ubuntu.com/ubuntu/ jammy-updates universe +# deb-src http://archive.ubuntu.com/ubuntu/ jammy-updates universe + +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu +## team, and may not be under a free licence. Please satisfy yourself as to +## your rights to use the software. Also, please note that software in +## multiverse WILL NOT receive any review or updates from the Ubuntu +## security team. +deb http://archive.ubuntu.com/ubuntu/ jammy multiverse +# deb-src http://archive.ubuntu.com/ubuntu/ jammy multiverse +deb http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse +# deb-src http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse + +## N.B. software from this repository may not have been tested as +## extensively as that contained in the main release, although it includes +## newer versions of some applications which may provide useful features. +## Also, please note that software in backports WILL NOT receive any review +## or updates from the Ubuntu security team. +deb http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse +# deb-src http://archive.ubuntu.com/ubuntu/ jammy-backports main restricted universe multiverse + +deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted +# deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted +deb http://security.ubuntu.com/ubuntu/ jammy-security universe +# deb-src http://security.ubuntu.com/ubuntu/ jammy-security universe +deb http://security.ubuntu.com/ubuntu/ jammy-security multiverse +# deb-src http://security.ubuntu.com/ubuntu/ jammy-security multiverse +``` + diff --git "a/doc/tutorials/ospp-kernelci/doc/\346\234\252\346\217\220\344\276\233\347\232\204\350\256\276\345\244\207\347\261\273\345\236\213-\350\207\252\345\256\232\344\271\211\350\256\276\345\244\207\347\261\273\345\236\213-Lip4a.md" "b/doc/tutorials/ospp-kernelci/doc/\346\234\252\346\217\220\344\276\233\347\232\204\350\256\276\345\244\207\347\261\273\345\236\213-\350\207\252\345\256\232\344\271\211\350\256\276\345\244\207\347\261\273\345\236\213-Lip4a.md" new file mode 100644 index 0000000000000000000000000000000000000000..423bc642c295c3321e75db3226cfcdc31c732d9b --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/\346\234\252\346\217\220\344\276\233\347\232\204\350\256\276\345\244\207\347\261\273\345\236\213-\350\207\252\345\256\232\344\271\211\350\256\276\345\244\207\347\261\273\345\236\213-Lip4a.md" @@ -0,0 +1,907 @@ +可以先按照之前的做法什么都不操作,**device-type** 存储在 master 中 + +### 确定源码中是否存在 + +```shell +feifei@localhost:~$ docker ps -a +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS + NAMES +314838a8259e local-lab-slave-1 "/root/entrypoint.sh…" 7 days ago Up 37 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp, 127.0.0.1:69->69/udp, 0.0.0.0:61950-62000->61950-62000/tcp, :::61950-62000->61950-62000/tcp local-lab-slave-1-1 +53eeb4fc811e local-master "/root/entrypoint.sh…" 7 days ago Up 16 hours 3079/tcp, 5500/tcp, 5555-5556/tcp, 8000-8001/tcp, 0.0.0.0:8000->80/tcp local-master-1 +``` + +然后进入 master 也就是 CONTAINER ID 为 **53eeb4fc811e** 的机器 + +```shell +feifei@localhost:~$ docker exec -it 53eeb4fc811e /bin/bash +root@master:/# +``` + +可以到 https://github.com/Linaro/lava/tree/master/etc/dispatcher-config/device-types 查看 + +如果你嫌麻烦,我在这里列出 + +```shell +root@master:/# ls usr/share/lava-server/device-types/ +aaeon-UPN-EHLX4RE-A10-0864.jinja2 +acer-R721T-grunt.jinja2 +acer-cb317-1h-c3z6-dedede.jinja2 +acer-cbv514-1h-34uz-brya.jinja2 +acer-chromebox-cxi4-puff.jinja2 +acer-chromebox-cxi5-brask.jinja2 +acer-cp514-2h-1130g7-volteer.jinja2 +acer-cp514-2h-1160g7-volteer.jinja2 +acer-cp514-3wh-r0qs-guybrush.jinja2 +acer-n20q11-r856ltn-p1s2-nissa.jinja2 +adb-nuc.jinja2 +alpine-db.jinja2 +am335x-sancloud-bbe.jinja2 +am437x-idk-evm.jinja2 +am57xx-beagle-x15.jinja2 +am6.jinja2 +apq8016-sbc-uboot.jinja2 +ar9331-dpt-module.jinja2 +arduino-nano-33-ble.jinja2 +arduino101.jinja2 +armada-370-db.jinja2 +armada-370-rd.jinja2 +armada-3720-db.jinja2 +armada-3720-espressobin.jinja2 +armada-375-db.jinja2 +armada-385-db-ap.jinja2 +armada-388-clearfog-pro.jinja2 +armada-388-clearfog.jinja2 +armada-388-gp.jinja2 +armada-398-db.jinja2 +armada-7040-db.jinja2 +armada-8040-db.jinja2 +armada-xp-db.jinja2 +armada-xp-gp.jinja2 +armada-xp-linksys-mamba.jinja2 +armada-xp-openblocks-ax3-4.jinja2 +arndale.jinja2 +asus-C433TA-AJ0005-rammus.jinja2 +asus-C436FA-Flip-hatch.jinja2 +asus-C523NA-A20057-coral.jinja2 +asus-CM1400CXA-dalboz.jinja2 +asus-cx9400-volteer.jinja2 +at91-sama5d2_xplained.jinja2 +at91-sama5d4_xplained.jinja2 +at91rm9200ek.jinja2 +at91sam9261ek.jinja2 +at91sam9g20ek.jinja2 +at91sam9m10g45ek.jinja2 +at91sam9x25ek.jinja2 +at91sam9x35ek.jinja2 +ava.jinja2 +avenger96.jinja2 +avh.jinja2 +b-u585i-iot02a.jinja2 +b2120h410.jinja2 +b2260.jinja2 +base-barebox.jinja2 +base-depthcharge.jinja2 +base-edk2.jinja2 +base-fastboot.jinja2 +base-grub.jinja2 +base-uboot.jinja2 +base.jinja2 +bcm2711-rpi-4-b.jinja2 +bcm2835-rpi-b-rev2.jinja2 +bcm2836-rpi-2-b.jinja2 +bcm2837-rpi-3-b-32.jinja2 +bcm2837-rpi-3-b.jinja2 +beagle-xm.jinja2 +beaglebone-black-barebox.jinja2 +beaglebone-black.jinja2 +cc13x2-launchpad.jinja2 +cc3220SF.jinja2 +cubietruck.jinja2 +cy8ckit-064s0s2-4343w.jinja2 +d02.jinja2 +d03.jinja2 +d2500cc.jinja2 +da850-lcdk.jinja2 +de0-nano-soc.jinja2 +dell-latitude-3445-7520c-skyrim.jinja2 +dell-latitude-5300-8145U-arcada.jinja2 +dell-latitude-5400-4305U-sarien.jinja2 +dell-latitude-5400-8665U-sarien.jinja2 +disco-l475-iot1.jinja2 +docker.jinja2 +dove-cubox.jinja2 +dra7-evm.jinja2 +dragonboard-410c.jinja2 +dragonboard-820c.jinja2 +dragonboard-845c.jinja2 +e850-96.jinja2 +exynos4-5-common.jinja2 +exynos5420-common.jinja2 +frdm-k64f.jinja2 +frdm-kw41z.jinja2 +fsl-ls-common.jinja2 +fsl-ls1012a-rdb.jinja2 +fsl-ls1028a-rdb.jinja2 +fsl-ls1043a-rdb.jinja2 +fsl-ls1046a-frwy.jinja2 +fsl-ls1046a-rdb.jinja2 +fsl-ls1088a-rdb.jinja2 +fsl-ls2088a-rdb.jinja2 +fsl-lx2160a-rdb.jinja2 +fsl-lx2162a-qds.jinja2 +fsl-s32v234sbc.jinja2 +fvp.jinja2 +gemini-ssi1328.jinja2 +hi6220-hikey-bl.jinja2 +hi6220-hikey-r2.jinja2 +hi6220-hikey.jinja2 +hi960-hikey.jinja2 +hifive-unleashed-a00.jinja2 +hifive-unmatched-a00.jinja2 +highbank.jinja2 +hip07-d05.jinja2 +hp-11A-G6-EE-grunt.jinja2 +hp-14-db0003na-grunt.jinja2 +hp-14b-na0052xx-zork.jinja2 +hp-x360-12b-ca0010nr-n4020-octopus.jinja2 +hp-x360-12b-ca0500na-n4000-octopus.jinja2 +hp-x360-14-G1-sona.jinja2 +hp-x360-14a-cb0001xx-zork.jinja2 +hsdk.jinja2 +i945gsex-qs.jinja2 +ifc6410.jinja2 +imx23-olinuxino.jinja2 +imx27-phytec-phycard-s-rdk.jinja2 +imx28-duckbill.jinja2 +imx53-qsrb.jinja2 +imx6dl-riotboard.jinja2 +imx6dl-sabreauto.jinja2 +imx6dl-sabresd.jinja2 +imx6dl-udoo.jinja2 +imx6q-nitrogen6x.jinja2 +imx6q-sabreauto.jinja2 +imx6q-sabrelite.jinja2 +imx6q-sabresd.jinja2 +imx6q-udoo.jinja2 +imx6q-var-dt6customboard.jinja2 +imx6qdl-common.jinja2 +imx6qp-sabreauto.jinja2 +imx6qp-sabresd.jinja2 +imx6qp-wandboard-revd1.jinja2 +imx6sl-evk.jinja2 +imx6sll-evk.jinja2 +imx6sx-sdb.jinja2 +imx6ul-14x14-evk.jinja2 +imx6ul-pico-hobbit.jinja2 +imx6ull-14x14-evk.jinja2 +imx6ull-evk.jinja2 +imx6ulz-14x14-evk.jinja2 +imx6ulz-lite-evk.jinja2 +imx6us7d-common.jinja2 +imx7d-sdb.jinja2 +imx7s-warp.jinja2 +imx7u-common.jinja2 +imx7ulp-evk.jinja2 +imx8dx-mek.jinja2 +imx8dxl-ddr3l-evk.jinja2 +imx8dxl-evk.jinja2 +imx8dxl-phantom-mek.jinja2 +imx8m-common.jinja2 +imx8mm-ddr4-evk.jinja2 +imx8mm-evk.jinja2 +imx8mm-innocomm-wb15-evk.jinja2 +imx8mn-ddr3l-ab2.jinja2 +imx8mn-ddr3l-evk.jinja2 +imx8mn-ddr4-evk.jinja2 +imx8mn-evk.jinja2 +imx8mp-ab2.jinja2 +imx8mp-ddr4-evk.jinja2 +imx8mp-evk.jinja2 +imx8mp-verdin-nonwifi-dahlia.jinja2 +imx8mq-evk.jinja2 +imx8mq-wevk.jinja2 +imx8mq-zii-ultra-zest.jinja2 +imx8q-common.jinja2 +imx8qm-mek.jinja2 +imx8qxp-mek.jinja2 +imx8u-common.jinja2 +imx8ulp-9x9-evk.jinja2 +imx8ulp-evk.jinja2 +imx9-common.jinja2 +imx91-11x11-evk.jinja2 +imx91p-11x11-evk.jinja2 +imx91p-9x9-qsb.jinja2 +imx93-11x11-evk-pmic-pf0900.jinja2 +imx93-11x11-evk.jinja2 +imx93-14x14-evk.jinja2 +imx93-9x9-qsb.jinja2 +imx95-19x19-evk.jinja2 +intel-ixp42x-welltech-epbx100.jinja2 +jetson-tk1.jinja2 +jh7100-beaglev-starlight.jinja2 +jh7100-starfive-visionfive-v1.jinja2 +jh7100-visionfive.jinja2 +juno-uboot.jinja2 +juno-uefi.jinja2 +juno.jinja2 +k3-am625-sk.jinja2 +kirkwood-db-88f6282.jinja2 +kirkwood-openblocks_a7.jinja2 +kontron-bl-imx8mm.jinja2 +kontron-kbox-a-230-ls.jinja2 +kontron-kswitch-d10-mmt-6g-2gs.jinja2 +kontron-kswitch-d10-mmt-8g.jinja2 +kontron-kswitch-d10-mmt-common.jinja2 +kontron-pitx-imx8m.jinja2 +kontron-sl28-common.jinja2 +kontron-sl28-var3-ads2.jinja2 +kv260.jinja2 +kvm.jinja2 +lava-slave-docker.jinja2 +lenovo-TPad-C13-Yoga-zork.jinja2 +lenovo-hr330a-7x33cto1ww-emag.jinja2 +lpcxpresso55s69.jinja2 +ls1021a-twr.jinja2 +lxc.jinja2 +mediatek-8173.jinja2 +meson-axg-s400.jinja2 +meson-g12-common.jinja2 +meson-g12a-sei510.jinja2 +meson-g12a-u200.jinja2 +meson-g12a-x96-max.jinja2 +meson-g12b-a311d-khadas-vim3.jinja2 +meson-g12b-a311d-libretech-cc.jinja2 +meson-g12b-odroid-n2.jinja2 +meson-gx-common.jinja2 +meson-gxbb-nanopi-k2.jinja2 +meson-gxbb-p200.jinja2 +meson-gxl-s805x-libretech-ac.jinja2 +meson-gxl-s805x-p241.jinja2 +meson-gxl-s905d-p230.jinja2 +meson-gxl-s905x-khadas-vim.jinja2 +meson-gxl-s905x-libretech-cc.jinja2 +meson-gxl-s905x-p212.jinja2 +meson-gxm-khadas-vim2.jinja2 +meson-gxm-q200.jinja2 +meson-sm1-khadas-vim3l.jinja2 +meson-sm1-odroid-c4.jinja2 +meson-sm1-s905d3-libretech-cc.jinja2 +meson-sm1-sei610.jinja2 +meson8b-ec100.jinja2 +meson8b-odroidc1.jinja2 +mimxrt1050_evk.jinja2 +minnowboard-common.jinja2 +minnowboard-max-E3825.jinja2 +minnowboard-turbot-E3826.jinja2 +moonshot-m400.jinja2 +morello.jinja2 +mps.jinja2 +mt8173-elm-hana.jinja2 +mt8183-kukui-jacuzzi-juniper-sku16.jinja2 +mt8186-corsola-steelix-sku131072.jinja2 +mt8192-asurada-rev1.jinja2 +mt8192-asurada-spherion-r0.jinja2 +mt8195-cherry-tomato-r2.jinja2 +mt8195-cherry-tomato-r3.jinja2 +musca-a.jinja2 +musca-b.jinja2 +musca-s.jinja2 +musca.jinja2 +mustang-grub-efi.jinja2 +mustang-uefi.jinja2 +mustang.jinja2 +n1sdp.jinja2 +nexus10.jinja2 +nexus4.jinja2 +nexus5x.jinja2 +nexus9.jinja2 +nrf52-nitrogen.jinja2 +nucleo-l476rg.jinja2 +nxp-ls2088.jinja2 +odroid-n2.jinja2 +odroid-x2.jinja2 +odroid-xu3.jinja2 +orion5x-rd88f5182-nas.jinja2 +overdrive.jinja2 +ox820-cloudengines-pogoplug-series-3.jinja2 +panda.jinja2 +pc-k10n78.jinja2 +peach-pi.jinja2 +pixel.jinja2 +poplar.jinja2 +qcom-qdf2400.jinja2 +qcs404-evb-1k.jinja2 +qcs404-evb-4k.jinja2 +qemu-aarch64.jinja2 +qemu.jinja2 +qrb4210-rb2.jinja2 +qrb5165-rb5.jinja2 +r8a7742-iwg21d-q7.jinja2 +r8a7743-iwg20d-q7.jinja2 +r8a7744-iwg20d-q7.jinja2 +r8a7745-iwg22d-sodimm.jinja2 +r8a77470-iwg23s-sbc.jinja2 +r8a774a1-hihope-rzg2m-ex.jinja2 +r8a774b1-hihope-rzg2n-ex.jinja2 +r8a774c0-ek874.jinja2 +r8a774e1-hihope-rzg2h-ex.jinja2 +r8a7791-porter.jinja2 +r8a7795-h3ulcb-kf.jinja2 +r8a7795-salvator-x.jinja2 +r8a77950-ulcb.jinja2 +r8a7796-m3ulcb-kf.jinja2 +r8a7796-m3ulcb.jinja2 +r8a779m1-ulcb.jinja2 +rcar-gen3-common.jinja2 +rk3288-miqi.jinja2 +rk3288-rock2-square.jinja2 +rk3288-veyron-jaq.jinja2 +rk3328-rock64.jinja2 +rk3399-gru-kevin.jinja2 +rk3399-khadas-edge-v.jinja2 +rk3399-puma-haikou.jinja2 +rk3399-roc-pc.jinja2 +rk3399-rock-pi-4b.jinja2 +rk3588-rock-5b.jinja2 +rpi-common.jinja2 +rzg1-common.jinja2 +rzg2-common.jinja2 +rzn1d.jinja2 +s32v234-evb.jinja2 +sama53d.jinja2 +sama5d34ek.jinja2 +sama5d36ek.jinja2 +sc7180-trogdor-kingoftown.jinja2 +sc7180-trogdor-lazor-limozeen.jinja2 +sdm845-mtp.jinja2 +seco-b68.jinja2 +seco-c61.jinja2 +sharkl2.jinja2 +sm8150-mtp.jinja2 +sm8250-mtp.jinja2 +sm8350-hdk.jinja2 +sm8350-mtp.jinja2 +sm8550-hdk.jinja2 +snow.jinja2 +soca9.jinja2 +socfpga-cyclone5-socrates.jinja2 +ssh.jinja2 +stm32-carbon.jinja2 +stm32l562e-dk.jinja2 +stm32mp157a-dhcor-avenger96.jinja2 +stm32mp157c-dk2.jinja2 +stm32mp157c-lxa-mc1.jinja2 +stm32mp157c-lxa-tac-gen1.jinja2 +stm32mp15x-eval.jinja2 +sun4i-a10-olinuxino-lime.jinja2 +sun50i-a64-bananapi-m64.jinja2 +sun50i-a64-pine64-plus.jinja2 +sun50i-h5-libretech-all-h3-cc.jinja2 +sun50i-h5-nanopi-neo-plus2.jinja2 +sun50i-h6-orangepi-3.jinja2 +sun50i-h6-orangepi-one-plus.jinja2 +sun50i-h6-pine-h64-model-b.jinja2 +sun50i-h6-pine-h64.jinja2 +sun5i-a13-olinuxino-micro.jinja2 +sun5i-gr8-chip-pro.jinja2 +sun5i-r8-chip.jinja2 +sun6i-a31-app4-evb1.jinja2 +sun7i-a20-cubieboard2.jinja2 +sun7i-a20-olinuxino-lime2.jinja2 +sun7i-a20-olinuxino-micro.jinja2 +sun8i-a23-evb.jinja2 +sun8i-a33-olinuxino.jinja2 +sun8i-a33-sinlinx-sina33.jinja2 +sun8i-a83t-allwinner-h8homlet-v2.jinja2 +sun8i-a83t-bananapi-m3.jinja2 +sun8i-h2-plus-bananapi-m2-zero.jinja2 +sun8i-h2-plus-libretech-all-h3-cc.jinja2 +sun8i-h2-plus-orangepi-r1.jinja2 +sun8i-h2-plus-orangepi-zero.jinja2 +sun8i-h3-bananapi-m2-plus.jinja2 +sun8i-h3-libretech-all-h3-cc.jinja2 +sun8i-h3-orangepi-pc.jinja2 +sun8i-r40-bananapi-m2-ultra.jinja2 +sun9i-a80-cubieboard4.jinja2 +sunxi-common.jinja2 +synquacer-acpi.jinja2 +synquacer-dtb.jinja2 +synquacer-uboot.jinja2 +synquacer.jinja2 +tc2.jinja2 +tegra124-common.jinja2 +tegra124-nyan-big.jinja2 +thunderx.jinja2 +upsquare.jinja2 +vexpress.jinja2 +x15-bl.jinja2 +x15.jinja2 +x86-atom330.jinja2 +x86-celeron.jinja2 +x86-pentium4.jinja2 +x86-x5-z8350.jinja2 +x86.jinja2 +xilinx-zcu102.jinja2 +root@master:/# +``` + +如果这里也没有你想要的 device-type 别急 可以查看 [Adding new device types — LAVA 2024.05 documentation (linaro.org)](https://validation.linaro.org/static/docs/v2/device-integration.html) 里面提供了 + +### 在其他地方获取,如 gitlab 或正在运行的 lavalab + +----- + +**Find a similar existing device type** + +There are a number of places to check for similar types of device which are already supported in LAVA V2. + +1. https://master.lavasoftware.org/scheduler/ 失效 +2. https://staging.validation.linaro.org/scheduler/ +3. https://validation.linaro.org/scheduler/ +4. https://lng.validation.linaro.org/scheduler/ 失效 +5. https://gitlab.com/lava/lava/tree/master/lava_scheduler_app/tests/device-types 可能是转移到其他目录了 我没找到 + +Check for: + +- similar bootloader +- similar deployment type +- similar deployment or boot process +- similar sequence of boot steps + +----- + +如果都没有的话,很遗憾可能你需要自己编写了 + +比如我手上的 Licheepi4a + +进入正题吧 + +## 从零编写 device-type + +**并不严谨的教学** + +这里给出 我编写的 Licheepi4a + +```jinja2 +{% extends 'base-uboot.jinja2' %} + +{% set uboot_mkimage_arch = 'riscv' %} +{% set console_device = console_device|default('ttyS0') %} +{% set baud_rate = baud_rate|default(115200) %} + +{% set booti_kernel_addr = '0x00200000' %} +{% set booti_dtb_addr = '0x03800000' %} +{% set booti_ramdisk_addr = '0x06000000' %} + +{% set uboot_initrd_high = '0xffffffffffffffff' %} +{% set uboot_fdt_high = '0xffffffffffffffff' %} + +{% set boot_character_delay = 100 %} + +{% set shutdown_message = 'The system will reboot now!' %} +{% set bootloader_prompt = bootloader_prompt|default('Light LPI4A#') %} + +"tftpboot {KERNEL_ADDR} {KERNEL}", +"tftpboot {RAMDISK_ADDR} {RAMDISK}", +"tftpboot {DTB_ADDR} {DTB}" +``` + +这是一个 Jinja2 模板,用于生成与 U-Boot 相关的配置文件,特别是为 RISC-V 架构设计的。以下是各部分的详细解释: + +### 模板结构 + +1. **扩展基模板**: + ```jinja + {% extends 'base-uboot.jinja2' %} + ``` + - 该行表示当前模板从 `base-uboot.jinja2` 继承,根据你当前的开发板以及操作系统要求定,我这里是 uboot + +2. **设置变量**: + ```jinja + {% set uboot_mkimage_arch = 'riscv' %} + {% set console_device = console_device|default('ttyS0') %} + {% set baud_rate = baud_rate|default(115200) %} + ``` + - `uboot_mkimage_arch`:设置 U-Boot 构建的架构为 `riscv`。 + - `console_device`:设置控制台设备,默认为 `ttyS0`,如果未传递其他值。 + - `baud_rate`:设置波特率,默认为 `115200`。 + +3. **设置内存地址**: + + ```jinja + {% set booti_kernel_addr = '0x00202000' %} + {% set booti_dtb_addr = '0x03800000' %} + {% set booti_ramdisk_addr = '0x06000000' %} + ``` + + - `booti_kernel_addr`:内核的加载地址。 + - `booti_dtb_addr`:设备树 Blob (DTB) 的加载地址。 + - `booti_ramdisk_addr`:初始 RAM 磁盘的加载地址。 + + 该如何获取内核加载地址呢,一是可以阅读开发板的官方文档,很遗憾,我在 Licheepi4a 的官方文档 [Lichee Pi 4A - Sipeed Wiki](https://wiki.sipeed.com/hardware/zh/lichee/th1520/lp4a.html) 翻找了很久没找到,但不代表一定没提供 + + 所以我采用先将 openEuler 24.03 LTS 安装到 licheepi4a 上, 在 boot 进行过程中查看 + + 那么首先要做的就是将 24.03 烧录进入 icheepi4a ,可以查看 openEuler 的官方文档 [RISC-V-LicheePi4A (openeuler.org)](https://docs.openeuler.org/zh/docs/24.03_LTS/docs/Installation/RISC-V-LicheePi4A.html) 下载地址在这里 [openEuler下载 | openEuler ISO镜像 | openEuler社区官网](https://www.openeuler.org/zh/download/?version=openEuler 24.03 LTS) + + + + ps : 1.实际上不需要网线 2.注意要区分与 licheepi4a 官方的镜像烧录方式,虽然那个是烧录 debian 的,但是和 openeuler的方式略有不同 + + + + 烧录完成就可以进行串口连接了,不知道可不可以直接用 type -c 接口进行串口连接,在网络上没检索到相关的信息,这里使用的是 + + 官方的 plus调试器 + + [Sipeed LicheePi 4A Risc-V TH1520 Linux SBC 开发板 荔枝派-淘宝网 (taobao.com)](https://item.taobao.com/item.htm?id=715508771884&sku_properties=-3%3A-3) ps:非广告 + + licheepi1 + + 然后将 plus调试器连接到主机上 + + 这里会引入一个问题就是 WSL 2 需要和 windows 共享 usb 接口,下文再说 + + 串口连接 我在 windows 上使用的是 **MobaXterm** ,只是使用的话可以参考 [嵌入式工程师都在用的全能终端神器—MobaXterm - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/452450152) + + 按下 RST 重启机器 在引导阶段 在 MobaXterm 串口终端中按下任意键 我按的空格,你应该按什么都行 。 + + ![licheepi2](img/硬件/licheepi2.png) + + 此时输入 h 可以看到一些帮助 + + 我们这里输入 printenv + + ```shell + Light LPI4A# printenv + aon_ram_addr=0xffffef8000 + arch=riscv + audio_ram_addr=0x32000000 + baudrate=115200 + board=light-c910 + board#=LP + board_name=light-c910 + boot_conf_addr_r=0xc0000000 + boot_conf_file=/extlinux/extlinux.conf + bootcmd=run bootcmd_load; bootslave; sysboot mmc ${mmcdev}:${mmcbootpart} any $boot_conf_addr_r $boot_conf_file; + bootcmd_load=run findpart;run load_aon;run load_c906_audio; load mmc ${mmcdev}:${mmcbootpart} $opensbi_addr fw_dynamic.bin + bootdelay=2 + cpu=c9xx + dtb_addr=0x03800000 + eth1addr=48:da:35:60:17:f0 + ethaddr=48:da:35:60:17:ef + fdt_addr_r=0x03800000 + fdt_high=0xffffffffffffffff + fdtcontroladdr=ffba7840 + fdtfile=thead/th1520-lichee-pi-4a.dtb + finduuid=part uuid mmc ${mmcdev}:${mmcpart} uuid + fwaddr=0x10000000 + gpt_partition=gpt write mmc ${mmcdev} $partitions + kdump_buf=180M + kernel_addr_r=0x00200000 + load_aon=load mmc ${mmcdev}:${mmcbootpart} $fwaddr light_aon_fpga.bin;cp.b $fwaddr $aon_ram_addr $filesize + load_c906_audio=load mmc ${mmcdev}:${mmcbootpart} $fwaddr light_c906_audio.bin;cp.b $fwaddr $audio_ram_addr $filesize + mmcbootpart=2 + mmcdev=0 + opensbi_addr=0x0 + partitions=name=table,size=2031KB;name=boot,size=500MiB,type=boot;name=root,size=-,type=linux,uuid=${uuid_rootfsA} + pxefile_addr_r=0x00600000 + ramdisk_addr_r=0x06000000 + scriptaddr=0x00500000 + splashimage=0x30000000 + splashpos=m,m + str_ram_addr=0xffe0000000 + uuid_rootfsA=80a5a8e9-c744-491a-93c1-4f4194fd690a + vendor=thead + + Environment size: 1375/131068 bytes + ``` + + 就可以获取你要的信息啦 + +4. **设置高地址限制**: + + ```jinja + {% set uboot_initrd_high = '0xffffffffffffffff' %} + {% set uboot_fdt_high = '0xffffffffffffffff' %} + ``` + + - `uboot_initrd_high` 和 `uboot_fdt_high`:设置初始 RAM 磁盘和设备树的高地址限制为最大值,表示允许使用的最高地址。 + +5. **设置 lava 输入字符的间隔**: + + ```jinja2 + {% set boot_character_delay = 100 %} + ``` + + - `boot_character_delay`:设置 lava 输入字符的时间,主要是为了模拟人类键盘输入,电脑输入过快可能会造成字符倒置等情况 + +6. **设置 shudown 提示词**: + + ```jinja2 + {% set shutdown_message = 'The system will reboot now!' %} + ``` + + - `shutdown_message`:设置成你的机器的提示词 默认是 ‘ The system is going down for reboot NOW’,lpi4a 不太一致, + + 实际上 lpi4a reboot时 甚至都不输出类似信息。 + +7. **设置引导提示词**: + + ```jinja2 + {% set bootloader_prompt = bootloader_prompt|default('Light LPI4A#') %} + ``` + + - `bootloader_prompt`:lpi4a 是 'Light LPI4A#‘ ,跟随你的被测试硬件 + +**TFTP 命令** + +```jinja +"tftpboot {KERNEL_ADDR} {KERNEL}", +"tftpboot {RAMDISK_ADDR} {RAMDISK}", +"tftpboot {DTB_ADDR} {DTB}" +``` +- 这些行定义了使用 TFTP 协议从服务器加载内核、RAM 磁盘和设备树的命令: + - `tftpboot {KERNEL_ADDR} {KERNEL}`:从 TFTP 服务器下载内核到指定的加载地址。 + - `tftpboot {RAMDISK_ADDR} {RAMDISK}`:下载初始 RAM 磁盘映像。 + - `tftpboot {DTB_ADDR} {DTB}`:下载设备树 Blob。 + +然后就是 + +## 配置 **board.yaml** + +也就是这里 + +```yaml +boards: + - name: qemu-test + type: qemu + slave: lab-slave-1 + - name: Lpi4A + type: LicheePi4A_4 + slave: lab-slave-1 + connection_command: telnet 192.168.137.1 20000 #这里应该修改为当前的ip + pdu_generic: ////远程控制电源的命令 + + #(echo "OFF"; sleep 1; echo "ON") | telnet 192.168.1.100 20001 使用串口 + #(echo "ON") | telnet 192.168.1.100 20001 + #(echo "OFF") | telnet 192.168.1.100 20001 + mosquitto_pub -h 192.168.0.158 -t "device/power" -m "RESET" + mosquitto_pub -h 192.168.0.158 -t "device/power" -m "ON" + mosquitto_pub -h 192.168.0.158 -t "device/power" -m "OFF" + uart: + idvendor: 0x0403 + idproduct: 0x6010 + devpath: "1" +``` + + + +ps: 测试时 我发现我的连接不上了,排查一大圈 发现是因为 WSL 2 默认情况下 ip 会随着 机器开关机而改变 导致 telnet 设置出现了问题 + +既然说到 telnet 那么就顺便讲下如何配置 + +## 配置串口 + +实际上你用什么串口工具连接设备都行 , 这里写下我的做法 + +### 1.安装NFS server + +```shell +sudo apt install nfs-kernel-server +vim /etc/exports //配置NFS共享目录 +/var/lib/lava/dispatcher/tmp *(rw,no_root_squash,no_all_squash,async,no_subtree_check) +sudo service nfs-kernel-server restart //配置完成后重启NFS server +``` + +### 2 安装ser2net + +安装 ser2net 为了部署主机通过 telnet 可以连接到测试设备 + +```shell +sudo apt install ser2net +sudo vim /etc/ser2net.yaml //配置串口信息 +``` + +```shell +# Find detailed documentation in ser2net.yaml(5) +# A fully featured configuration file is in +# /usr/share/doc/ser2net/examples/ser2net.yaml.gz +# +# If you find your configuration more useful than this very simple +# one, please submit it as a bugreport + +define: &banner \r\nser2net port \p device \d [\B] (Debian GNU/Linux)\r\n\r\n + +connection: &con0827 + accepter: tcp,20000 + enable: on + options: + banner: *banner + kickolduser: true + telnet-brk-on-sync: true + connector: serialdev, + /dev/ttyUSB1, + 115200n81,local +connection: &con0828 + accepter: tcp,20001 + enable: on + options: + banner: *banner + kickolduser: true + telnet-brk-on-sync: true + connector: serialdev, + /dev/ttyUSB2, + 9600n81,local +``` + +```shell +sudo service ser2net restart //重启ser2net service +``` + +此时就可以用 + +```shell +telnet 192.168.137.1 20000 或 telnet localhost 20000 等方式 访问/dev/ttyUSB1 即 licheepi4a +``` + +如果你和我一样使用的是 2 这里就需要共享 windows 的 usb 接口,我的做法是这样 + +使用 USBIPD-WIN ,可以参考 微软的官方档案 [连接 USB 设备 | Microsoft Learn ](https://learn.microsoft.com/zh-cn/windows//connect-usb) 这里就不在赘述了 + +既然谈到这里了就顺便解决下开发板的网络问题吧 + +如果你有路由器当然可以直接连接到到板子上 ,如果你像我一样**寒酸**,只有一台主机和无线网络的话 可以参考 [开发板上网(保姆级教程)_开发板联网-CSDN博客](https://blog.csdn.net/weixin_56862703/article/details/132412188) ,来配置网关使用,让板子使用主机的网络。 + +## 编写 job + +解决了 device-type 的问题还需要解决 job 的问题,最重要的便是如何获取适合 licheepi4a 的 roofts 文件。以及dtb文件 + +这里给出一个 licheepi4a smoke-test 定义 + +```yaml +device_type: LicheePi4A_4 +job_name: licheepi-smoke-test +context: + boot_character_delay: 1000 + extra_nfsroot_args: ",nolock,nfsvers=3" +timeouts: + job: + minutes: 301 + action: + minutes: 300 + actions: + power-off: + seconds: 30 +priority: medium +visibility: public +metadata: + # please change these fields when modifying this job for your own tests. +# ACTION_BLOCK +actions: +- deploy: + timeout: + minutes: 20 + to: tftp + kernel: + url: file:///home/2024ospp-large-files/Image + type: image + dtb: + url: file:///home/2024ospp-large-files/licheepi4a/thead/th1520-lichee-pi-4a.dtb + nfsrootfs: + url: file:///home/2024ospp-large-files/openeuler-rootfs.tar.gz + compression: gz +- boot: + timeout: + minutes: 3 + method: qemu + media: tmpfs + prompts: ["root@openeuler-riscv64"] + auto_login: + login_prompt: "localhost login:" + username: root + password_prompt: "Password:" + password: openEuler12#$ + # TEST_BLOCK +- test: + timeout: + minutes: 10 + definitions: + - repository: https://git.linaro.org/lava-team/lava-functional-tests.git + from: git + path: lava-test-shell/smoke-tests-basic.yaml + name: smoke-tests +``` + +参考 [lava-docker细节解释 ](./lava-docker细节解释.md) 中 如何编写 ACTION_BLOCK + +[NJU Mirror](https://mirrors.nju.edu.cn/openeuler/openEuler-24.03-LTS/embedded_img/riscv64/lpi4a/) 是 openEuler 提供的 Licheepi4a 资源仓库 ,其他镜像仓库也类似 + +这里的重点在于,嵌入式设备并没有 qemu 所谓的 启动脚本 也没有 image 等资源 需要我们自己构建 + +### 获取 Image 和 dtbs + +构建的方法 + +```shell +git clone https://gitee.com/feifei-fertilizer/riscv-kernel.git +cd riscv-kerner.git +git checkout OLK-6.6 +``` + +由于我们只需要 Image 和 dtbs文件 + +```shell +make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- openeuler_defconfig +make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j1 Image dtbs WERROR=n +``` + +tips:这里不需要使用 arch/riscv/configs 下的 th1520_defconfig 根据 riscv-kernel 的提交记录 ,已经和 defconfig 合并 ,这里直接使用 openeuler_deconfig 即可,这里 使用 -j1 是为了方便排查错误。 + +```shell +feifei@localhost:~/oerv24.03-LTS$ ls ~/riscv-kernel/arch/riscv/configs/ +32-bit.config defconfig nommu_k210_sdcard_defconfig openeuler_defconfig sg2042_defconfig +64-bit.config nommu_k210_defconfig nommu_virt_defconfig rv32_defconfig th1520_defconfig +``` + +完成之后便会在 output 中获得构建的内容 + +这里我想提一下 可能是我自己环境的问题,构建我花了很长时间,也用了很多工具链,首先是在 ubuntu 22.03 上,直接使用官方仓库下载的 riscv64-linux-gnu-gcc 应该是 gcc 11,出现了一些问题 之后 我又安装了比较新的版本 也试过源码,无果。最后是在 manjaro 上才构建成功的 ,所以我这里提供我的信息 ,如果构建不成功 也许可以参考 + +```shell +riscv64-linux-gnu-gcc --version +riscv64-linux-gnu-gcc (GCC) 14.1.0 +Copyright (C) 2024 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +``` + +### 获取 roofts + +roofts 文件,可以在 [Nginx Directory (iscas.ac.cn)](https://mirror.iscas.ac.cn/openeuler-sig-riscv/openEuler-RISC-V/testing/2403LTS-test/v1/) 获取,也可以自己手动构建 + +由于 默认的 reboot 适配有问题 https://lists.lavasoftware.org/archives/list/lava-users@lists.lavasoftware.org/thread/CH3U475AGESVN4LYBUA4YVRFUTHOZ2LD/ + +## 修改 docker-compose.yml + +你需要先了解 docker-compose 中的内容如何生成 , [lava-docker细节解释](./lava-docker细节解释.md) 里有简单的描述 + +看下我的 + +```yml +services: + lab-slave-1: + build: + context: lab-slave-1 + dns_search: '' + device: + - /dev/Lpi4A:/dev/Lpi4A #默认是这样的 + environment: + LAVA_DISPATCHER_IP: 192.168.0.158 + LAVA_MASTER: master + hostname: lab-slave-1 + ports: + - 192.168.0.158:69:69/udp + - 61950-62000:61950-62000 + - 80:80 + volumes: + - /home/feifei/ospp/2024ospp-large-files/ubuntu/boot:/boot + - /home/feifei/ospp/2024ospp-large-files/ubuntu/modules:/lib/modules + - /home/feifei/ospp/2024ospp-large-files:/home/2024ospp-large-files + - /var/lib/lava/dispatcher/tmp:/var/lib/lava/dispatcher/tmp + master: + build: + context: master + hostname: master + ports: + - 0.0.0.0:8000:80 + volumes: + - /home/feifei/ospp/2024ospp-large-files/ubuntu/boot:/boot + - /home/feifei/ospp/2024ospp-large-files/ubuntu/modules:/lib/modules + - /home/feifei/ospp/2024ospp/device-type/Lpi4A.jinja2:/usr/share/lava-server/device-types/Lpi4A.jinja2 + - /home/feifei/ospp/2024ospp/device-type/LicheePi4A_4.jinja2:/usr/share/lava-server/device-types/LicheePi4A_4.jinja2 +version: '2.4' + +``` + +`dev/Lpi4A:/dev/Lpi4A` 应修改为 `/dev/ttyUSB1:/dev/Lpi4A` 其中 `ttyUSB1` 指的是串口连接的设备号 diff --git "a/doc/tutorials/ospp-kernelci/doc/\347\224\265\346\272\220\346\216\247\345\210\266.md" "b/doc/tutorials/ospp-kernelci/doc/\347\224\265\346\272\220\346\216\247\345\210\266.md" new file mode 100644 index 0000000000000000000000000000000000000000..779b41b6bedfe363d2f81c01c55742a27d356fc5 --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/\347\224\265\346\272\220\346\216\247\345\210\266.md" @@ -0,0 +1,255 @@ +电源控制并不是 **board.yaml** 的必选项,但总有需要的情形 + +这里我给出两种控制的方案 + +## **1.使用 mqtt + esp8266** + +### 配置 Mosquitto 服务 + +安装 mqtt sever, 这里使用的是 mosquitto,安装方法可以参考 https://www.vultr.com/docs/install-mosquitto-mqtt-broker-on-ubuntu-20-04-server/ + +这里将 Mosquitto 服务器 安装到 主机上 + +```shell +sudo apt update +sudo apt install mosquitto mosquitto-clients +sudo systemctl enable mosquitto.service +``` + +配置mosquitto, 创建配置文件 + +```shell +sudo vim /etc/mosquitto/conf.d/default.conf +``` + +创建 /etc/mosquitto/passwd 文件 + +````shell +sudo vim /etc/mosquitto/passwd +```` + +编辑用户名密码 + +````shell +: //用户名:密码 +```` + +使用mosquitto_passwd将密码文件 /etc/mosquitto/passwd 加密 + +````shell +sudo mosquitto_passwd -U /etc/mosquitto/passwd +```` + +查看是否加密成功 + +````shell +sudo cat /etc/mosquitto/passwd +```` + +配置完成后重启mosquitto service + +````shell +sudo systemctl restart mosquitto +```` + +### 向 esp8266 烧录控制程序 + +安装 Arduino IDE + +然后可以参考 [ESP8266+继电器+MQTT+VUE 实现远程开关灯_esp8266-01s电路图-CSDN博客](https://blog.csdn.net/qq_31762741/article/details/132635616) 和[ESP8266 + MQTT :如何实现 LED 灯的远程控制_esp8266 + mqtt实现远程控制led灯-CSDN博客](https://blog.csdn.net/emqx_broker/article/details/112716509) + +```c +#include +#include + +// WiFi 配置 +const char* ssid = "feifei_cpe"; // 替换为你的 WiFi SSID +const char* password = "feifei0827"; // 替换为你的 WiFi 密码 + +// MQTT 服务器配置 +const char* mqtt_server = "192.168.0.158"; // 替换为您的 MQTT 服务器地址 +const char* mqtt_topic = "device/power"; // 控制主题 + +// GPIO 引脚 +const int relayPin = 4; // 继电器控制引脚 + +WiFiClient espClient; +PubSubClient client(espClient); + +void setup() { + Serial.begin(115200); + pinMode(relayPin, OUTPUT); + digitalWrite(relayPin, LOW); // 初始状态关闭继电器 + + // 连接到 WiFi + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + Serial.println("连接中..."); + } + Serial.println("WiFi 连接成功"); + + // 设置 MQTT 服务器 + client.setServer(mqtt_server, 1883); + client.setCallback(callback); + + // 连接到 MQTT + reconnect(); +} + +void loop() { + if (!client.connected()) { + reconnect(); + } + client.loop(); +} + +// MQTT 消息回调函数 +void callback(char* topic, byte* payload, unsigned int length) { + String message; + for (int i = 0; i < length; i++) { + message += (char)payload[i]; + } + + if (message == "ON") { + digitalWrite(relayPin, HIGH); // 打开继电器 + Serial.println("电源已打开"); + } else if (message == "OFF") { + digitalWrite(relayPin, LOW); // 关闭继电器 + Serial.println("电源已关闭"); + } else if (message == "RESET") { + Serial.println("重置设备..."); + digitalWrite(relayPin, LOW); // 关闭继电器 + Serial.println("电源已关闭"); + delay(500); + digitalWrite(relayPin, HIGH); // 打开继电器 + Serial.println("电源已打开"); + } +} + +// 连接到 MQTT 服务器 +void reconnect() { + while (!client.connected()) { + Serial.print("连接到 MQTT..."); + if (client.connect("ESP8266Client")) { + Serial.println("连接成功"); + client.subscribe(mqtt_topic); + } else { + Serial.print("失败,状态码="); + Serial.print(client.state()); + delay(2000); + } + } +} +``` + +只是一个简单的电源控制函数,也只针对了一个继电器的情况,暂时也没有复用性 + +```shell +mosquitto_pub -h 192.168.0.158 -t "device/power" -m "RESET" +mosquitto_pub -h 192.168.0.158 -t "device/power" -m "ON" +mosquitto_pub -h 192.168.0.158 -t "device/power" -m "OFF" +``` + +可以通过这个控制 继电器 + +将安装 mosquitto-clients 的脚本映射到 master 和 salve 机器中 ,就可以远程控制继电器了 + +**存在的问题** + +我买的 esp8266 不支持 5G 频段,这让我排查了很久,当然你可以买支持 5g 频段的类似 wifi 开发板,**如果你看到这里请注意** + +这里需要 master 和 slave 的环境中都有 mosquitto-clients + +我的方法比较笨就是 在构建好的 master 和 slave 的 dockerfile 中加入 + +```dockerfile +RUN apt-get update && \ + apt-get install -y mosquitto-clients && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +COPY /etc/mosquitto/mosquitto.conf /etc/mosquitto/mosquitto.conf +``` + +还要记得要将 out/put 下的 docker compose 中的 + +```yml +services: + lab-slave-1: + build: + context: lab-slave-1 + devices: + - /dev/ttyUSB1:/dev/Lpi4A- + dns_search: '' + environment: + LAVA_DISPATCHER_IP: 127.0.0.1 + LAVA_MASTER: master + hostname: lab-slave-1 + ports: + - 127.0.0.1:69:69/udp + - 61950-62000:61950-62000 + - 80:80 + volumes: + - /home/feifei/ospp/2024ospp-large-files/ubuntu/boot:/boot + - /home/feifei/ospp/2024ospp-large-files/ubuntu/modules:/lib/modules + - /home/feifei/ospp/2024ospp-large-files:/home/2024ospp-large-files + - /var/lib/lava/dispatcher/tmp:/var/lib/lava/dispatcher/tmp + - /usr/bin:/usr/bin/mosquitto_clients # 映射整个 bin 目录 + master: + build: + context: master + hostname: master + ports: + - 0.0.0.0:8000:80 + volumes: + - /home/feifei/ospp/2024ospp-large-files/ubuntu/boot:/boot + - /home/feifei/ospp/2024ospp-large-files/ubuntu/modules:/lib/modules + - /home/feifei/ospp/2024ospp/device-type/Lpi4A.jinja2:/usr/share/lava-server/device-types/Lpi4A.jinja2 + - /usr/bin:/usr/bin/mosquitto_clients # 映射整个 bin 目录 +``` + + + +## 2.使用其他开发板 + 串口 + +1. 我使用了 Arduino uno3 ,实际上都差不多 毕竟都只是使用了最简单的 gpio ,烧录方法和 esp8266 类似,由于没用到 mqtt库反而更简单,然后直接让 slave 与 Arduino uno3 串口通信来控制继电器 ,缺点在于 master 无法直接控制 slave 连接的设备的电源,需要和 slave 通信间接控制,当连接的设备多的时候 显然不太好控制 + + 和 esp8266 的类似 + + ```c + // 定义继电器连接的引脚 + const int relayPin = 4; + + void setup() { + // 初始化继电器引脚为输出模式 + pinMode(relayPin, OUTPUT); + // 初始状态为关闭继电器 + digitalWrite(relayPin, LOW); + } + + void loop() { + // 打开继电器 + digitalWrite(relayPin, HIGH); + Serial.println("Relay ON"); + delay(1000); // 延时1秒 + + // 关闭继电器 + digitalWrite(relayPin, LOW); + Serial.println("Relay OFF"); + delay(1000); // 延时1秒 + } + ``` + + ```shell + (echo "OFF"; sleep 1; echo "ON") | telnet 192.168.0.158 20001 + (echo "ON") | telnet 192.168.0.158 20001 + (echo "OFF") | telnet 192.168.0.158 20001 + ``` + + + +2. 使用了 canmv-k230 v1.1,由于我想整个活,尝试使用他的针脚 ,然而首先官方没提供 针脚图与实际针脚的对应关系图,其次由于canmv-k230 的针脚有多个功能 ,所以需要编辑该针脚的功能,调用基本的 gpio 功能,但由于上面提到的**没有针脚图**,我根本不知道 我写的程序能否正常运行,更不知道对应的针脚,穷举也不行。官方文档提供的 api 也不行,倒腾了两三天最后选择投降,中间还麻烦懂硬件和嵌入式的朋友帮我找找资料,无果。 + +到这里就做好了最基础的电源控制啦 + diff --git "a/doc/tutorials/ospp-kernelci/doc/\347\274\226\345\206\231job\345\222\214testcase.md" "b/doc/tutorials/ospp-kernelci/doc/\347\274\226\345\206\231job\345\222\214testcase.md" new file mode 100644 index 0000000000000000000000000000000000000000..55696ce3b3d3c526b0fec7d17707190036179495 --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/\347\274\226\345\206\231job\345\222\214testcase.md" @@ -0,0 +1,412 @@ +## job 模板 + +这里有几点建议 + +一,要查看官方文档,从那里可以了解到一些 job 如何编写 + +二,查看源码,这里包括 device-type 的源码,要查看你想编写的 板子的 device-type 以及 它是由哪些扩展来的, 大部分都是 uboot ,而 uboot 又是由 base 扩展而来。可以通过了解这些来查看你的 job 可以填写那些参数 + +三,可以直接去查看他人已有的 job ,很多启动命令是不常用,甚至连官网的文档都没提到的,比如 soft_reboot + +四,尝试直接运行你的 job ,lava 会给出一些提示 (不符合语法的话,是过不了 lava 的检测的 ),可以按照提示来 我认为比较重要的部分是从 提供 Image 根文件系统等资源,到 boot 启动这个部分, 在之前的章节也有过介绍。你可以观察 lava 的运作方式 ( lava 运行会输出较为完整的 log ) ,来按需修改你的 job 。最后达成你的目的 + +----- + +官网建议大家从 qemu 入手,这里给出官网的最基础的 job 模板 以及一些字段的解释 + +```yaml +# Your first LAVA JOB definition for an x86_64 QEMU +device_type: qemu +#一个标签,必须与要向其提交此作业的实例上声明的设备类型匹配。每种设备类型都可以有一个或多个可用设备。在本例中为 qemu +job_name: QEMU pipeline, first job +#此作业的自由文本名称。此名称在服务器端表中使用允许使用任何有效的 YAML 字符串,因此逗号、大写和空格都可以 +timeouts: + job: + minutes: 15 + action: + minutes: 5 + connection: + minutes: 2 +# 在 LAVA 测试作业中可能会出现一系列问题,因此测试编写者需要指示作业的某些部分应该花费多长时间 +priority: medium +#支持 [0, 100] 中的任何整数。还提供三个快捷键:high(100)、medium(50)和low(0)。调度程序在对队列进行排序时会考虑作业优先级 +visibility: public +#支持 public、personal 和 group 的值,控制允许查看作业和作业生成的结果的人员。这包括结果是否可用于查询和图表 + +# context allows specific values to be overridden or included +context: + # tell the qemu template which architecture is being tested + # the template uses that to ensure that qemu-system-x86_64 is executed. + arch: amd64 +#并非所有测试作业都会使用作业上下文,它可以覆盖某些服务器端设备配置模板。在这种情况下,arch: amd64 将模板设置为在启动仿真时使用 qemu-system-x86_64 可执行文件 +metadata: + # please change these fields when modifying this job for your own tests. + docs-source: first-job + docs-filename: qemu-pipeline-first-job.yaml +#一旦测试作业成为自动提交或 CI循环的一部分,就需要使用元数据来标识每个提交,提供有关与上次测试作业相比发生的确切变化的信息,以及有关其他用户如何修改测试作业构件以扩展或调试结果的信息 +# ACTION_BLOCK +actions: +# DEPLOY_BLOCK +- deploy: +#下载启动设备所需的文件,并准备要在测试操作中运行的文件叠加层 + timeout: + minutes: 5 + to: tmpfs + images: + rootfs: + image_arg: -drive format=raw,file={rootfs} + url: https://images.validation.linaro.org/kvm/standard/stretch-2.img.gz + compression: gz +#deploy 支持本地和网络资源多种格式 也可以选择 +# BOOT_BLOCK +- boot: +#指定启动设备的方法和提示符,这些提示将指示设备是否被视为已正确启动 + timeout: + minutes: 2 + method: qemu + media: tmpfs + prompts: ["root@debian:"] + auto_login: + login_prompt: "login:" + username: root + +# TEST_BLOCK +- test: + timeout: + minutes: 5 + definitions: + - repository: http://git.linaro.org/lava-team/lava-functional-tests.git + from: git + path: lava-test-shell/smoke-tests-basic.yaml + name: smoke-tests + - repository: https://git.linaro.org/lava-team/lava-functional-tests.git + from: git + path: lava-test-shell/single-node/singlenode03.yaml + name: singlenode-advanced +``` + +deploy 可以用的文件有网络资源和本地资源 + +网络资源:输入其网络资源的 url 即可 + +本地资源,首先要将其映射到 lava slave 容器中,在 [lava-docker细节解释 ](./lava-docker细节解释.md) 中有提到过如何映射 ( 修改 lavalab-gen.py ) + +![job和testcase1](img/job和testcase/job和testcase1.png) + +第 462 行的内容则是 映射主机的文件到 docker 容器,这里我将主机的 `/home/feifei/ospp/2024ospp-large-files` 映射为容器的 `/home/2024ospp-large-files` + +所以 lava job 在编写时就要写容器内部的路径 如下面这样 + +```yaml +- deploy: + timeout: + minutes: 20 + to: tmpfs + images: + kernel: + image_arg: -kernel {kernel} + url: file:///home/2024ospp-large-files/Image + rootfs: + image_arg: -drive file={rootfs},format=raw,id=hd0 + url: file:///home/2024ospp-large-files/openeuler-rootfs.img +``` + +一些实际可能遇到的问题在 [lava-docker细节解释 ](./lava-docker细节解释.md) 和 [未提供的设备类型-自定义设备类型-Licheepi 4a](./未提供的设备类型-自定义设备类型-Lip4a.md) 中有涉及过一部分 + +deploy 和 boot 的 参数很多 + +boot 更详细内容可以查看 [Boot Action Reference — LAVA 2024.09 documentation (lavasoftware.org)](https://docs.lavasoftware.org/lava/actions-boot.html#index-13) + +deploy 可以查看[部署操作参考 — LAVA 2024.09 文档 --- Deploy Action Reference — LAVA 2024.09 documentation (lavasoftware.org)](https://docs.lavasoftware.org/lava/actions-deploy.html#index-3) + +### 可选与必选字段 + +#### 必选字段 + +1. **device_type**: +2. **job_name**: +3. **timeouts**: +4. **actions**: + +5. **at least one action block**: + +#### 可选字段 + +1. **priority**: +2. **visibility**: +3. **context**: +4. **metadata**: +5. **timeout** (在各个块中): + + - 可以选择在每个 `deploy`、`boot` 和 `test` 块中定义超时 +6. **images** (在 `deploy` 块中): +- 测试已经配置好的设备时 +7. **prompts** (在 `boot` 块中): +8. **auto_login** (在 `boot` 块中): +9. **definitions** (在 `test` 块中): + +## 获取测试用例的两种方式 + +### 1.首先是自己编写 + +可以查看 [Glossary of terms — LAVA 2024.05 documentation (lavasoftware.org)](https://docs.lavasoftware.org/lava/glossary.html#term-job-definition) + +```yaml +# TEST_BLOCK +- test: + timeout: + minutes: 600 + definitions: + - repository: + metadata: + format: Lava-Test Test Definition 1.0 + run: + steps: + - yum install -y git make gcc flex bison clang + - df -h + - cd /root + - git clone https://gitee.com/feifei-fertilizer/riscv-kernel.git + - cd riscv-kerner.git + - git checkout OLK-6.6 + - make defconfig + - make -C tools/testing/selftests + - make -C tools/testing/selftests TARGETS=clone3 run_tests + from: inline #表示在当前主机上 + name: kselftest-inline + path: inline/kselftest.yaml +``` + +这是一个基于内核源码的 **kselftest** + +from 字段写成 inline + +然后填入一些描述 definitions, name 等 + +steps 字段 填入你需要的命令即可 + +这其实与你直接在机器上 敲命令没什么区别,重要的当然就是你要确保你自己在机器上可以跑通 + +可以注意下的是 name 与 path 字段最好相关 比如这里 name 和 path 都是 kselftest + +### 2.基于test-definitions + +可以通过 clone [Linaro/test-definitions: Test definitions work with and without LAVA (github.com)](https://github.com/Linaro/test-definitions) 来直接使用其准备好的测试 + +根据描述官方文档描述 [test-definitions/docs/index.md 在 master ·Linaro/测试定义 (github.com)](https://github.com/Linaro/test-definitions/blob/master/docs/index.md) + +这里给出 ltp.yaml的内容 https://github.com/Linaro/test-definitions/blob/master/automated/linux/ltp/ltp.yaml + +```yaml +metadata: + name: ltp + format: "Lava-Test Test Definition 1.0" + description: "Run LTP test suite on Ubuntu" + maintainer: + - milosz.wasilewski@linaro.org + - fathi.boudra@linaro.org + os: + - ubuntu + scope: + - functional + devices: + - all +params: + TST_CMDFILES: syscalls,mm,math,timers,fcntl-locktests,ipc,fsx,fs,hugetlb,io,nptl,pty,containers,fs_bind,filecaps,admin_tools,connectors + + # SKIPFILE can be a filename from dir ./automated/linux/ltp/, an http URL, + # or a skipgen style yaml file. + # Examples: + # SKIPFILE: "skipfile-lsk-juno" # is a known file present in + # # dir ./automated/linux/ltp/ + # SKIPFILE: "http://people.linaro.org/~naresh.kamboju/skipfile" + # SKIPFILE: "skipfile-lkft.yaml" # yaml file that will be parsed with + # # skipgen. Must use "yaml" extention. + # NOTE: busybox wget may not work with https link so prefer to use http + SKIPFILE: "" + + # BOARD, BRANCH, and ENVIRONMENT may be specified and may be used when + # generating a skipfile using a yaml skipfile and skipgen. + BOARD: "" + BRANCH: "" + LTP_TMPDIR: "/ltp-tmp" + LTP_INSTALL_PATH: "/opt/ltp" + ENVIRONMENT: "" + + SKIP_INSTALL: false + # Slow machines need more timeout Default is 5min and multiply * TIMEOUT_MULTIPLIER + TIMEOUT_MULTIPLIER: 3 + # root's password. Needed by ltp/su01. + ROOT_PASSWD: root + + # New kirk runner (https://github.com/linux-test-project/kirk.git) + # Needs to be installed onto the rootfs. + # Set RUNNER to full path to kik or to kirk if its in the PATH. + RUNNER: "" + + # If the following parameter is set, then the LTP suite is + # cloned and used unconditionally. In particular, the version + # of the suite is set to the commit pointed to by the + # parameter. A simple choice for the value of the parameter + # is, e.g., HEAD. If, instead, the parameter is + # not set, then the suite present in TEST_DIR is used. + # LTP version + LTP_VERSION: "" + + # If next parameter is set, then the LTP suite is cloned + # from the URL in TEST_GIT_URL. Otherwise it is cloned from the + # standard repository for the suite. Note that cloning is done + # only if LTP_VERSION is not empty + TEST_GIT_URL: "" + + # If next parameter is set, then the LTP suite is cloned to or + # looked for in TEST_DIR. Otherwise it is cloned to $(pwd)/ltp + TEST_DIR: "" + + # BUILD_FROM_TAR, if you want to download and build LTP from + # a released tarball, set BUILD_FROM_TAR to 'true'. You have to + # specify the LTP_VERSION to a release e.g., 20180926. + BUILD_FROM_TAR: "false" + + # Number of shards that will be done, default 1 which is the same as no sharding. + SHARD_NUMBER: 1 + + # Which bucket to run, default '1' which is the same as no sharding, run it as LTP upstream decides. + SHARD_INDEX: 1 +run: + steps: + - cd ./automated/linux/ltp/ + - ./ltp.sh -T "${TST_CMDFILES}" -s "${SKIP_INSTALL}" -v "${LTP_VERSION}" -M "${TIMEOUT_MULTIPLIER}" -R "${ROOT_PASSWD}" -r "${RUNNER}" -b "${BOARD}" -d "${LTP_TMPDIR}" -g "${BRANCH}" -e "${ENVIRONMENT}" -i "${LTP_INSTALL_PATH}" -S "${SKIPFILE}" -p "${TEST_DIR}" -u "${TEST_GIT_URL}" -t "${BUILD_FROM_TAR}" -n "${SHARD_NUMBER}" -c "${SHARD_INDEX}" + - ../../utils/send-to-lava.sh ./output/result.txt +``` + +看下有哪些部分组成 + +1. 元数据部分 + +- metadata + + : 描述测试用例的基本信息。 + + - **name**: 测试用例的名称,`ltp`。 + - **format**: 指定测试定义的格式版本,这里是 "Lava-Test Test Definition 1.0"。 + - 等 + +2. 参数部分 + +- params + + : 定义测试用例的参数,以下是主要参数的说明: + + - **TST_CMDFILES**: 指定要运行的 LTP 测试命令文件列表。 + - **SKIPFILE**: 可选的跳过文件,可以是本地文件、HTTP URL 或 YAML 文件,用于指定应跳过的测试 + - **等** + +3. 运行步骤 + +run 字段 + +- **steps**: 定义测试执行的步骤,包含以下内容: + 1. `cd ./automated/linux/ltp/`: 切换到 LTP 测试的目录。 + 2. `./ltp.sh ...`: 运行 `ltp.sh` 脚本,传入多个参数以配置测试运行。 + 3. `../../utils/send-to-lava.sh ./output/result.txt`: 调用一个脚本,将测试结果发送到 Lava 服务器,结果存储在 `./output/result.txt` 文件中。 + +我们在 job 中调用 可以按照以下格式来 + +```yaml +- test: + timeout: + minutes: 600 + definitions: + - repository: https://github.com/Linaro/test-definitions.git + from: git + path: automated/linux/ltp/ltp.yaml + parameters: + TST_CMDFILES: syscalls + SKIPFILE: skipfile-lkft.yaml + BOARD: qemu + BRANCH: master + ENVIRONMENT: production + TIMEOUT_MULTIPLIER: '30' + ROOT_PASSWD: openEuler12#$ + BUILD_FROM_TAR: true + LTP_VERSION: 20240524 + LTP_TMPDIR: /scratch + name: ltp-syscalls-tests +``` + +repository: 制定了地址 + +from:表示来源是 git + +parameters 表示提供的参数 参数都有哪些,对应 automated/linux/ltp/ltp.yaml 文件中的预留的 params + +按需填写你的信息即可 ,脚本会自动化的把这些参数提供给 test-definitions 中对应的 sh 脚本,来替你执行 shell 命令 + +可以对照着 inline 的测试用例查看 + +## 测试用例 + +通过观察 test-definitions 提供的 测试用例, + +大致的模板是这样的 + +```yaml +metadata: + name: <测试用例名称> + format: "Lava-Test Test Definition 1.0" # 或其他格式 + description: "<测试用例描述>" + maintainer: + - <维护者邮箱> + os: + - <支持的操作系统> + scope: + - <测试范围> + devices: + - <支持的设备或设备类型> + +params: + <参数名>: <默认值或说明> + ... + +run: + steps: + - <要执行的命令或脚本> + - <后续步骤> + ... +``` +LAVA 测试定义包括 Metadata,params,run 三个不可缺少的字段 ,其中 Metadata 中有可选字段和必选字段 + +- 必选 + + format + + name + + description + + version : "1.0" 如果文件不受版本控制(即不在 git 存储库中),则还必须在元数据中指定文件的**版本** + +- 可选 + + maintainer + + os + + scope + + devices + + +steps 可以直接 使用命令,也可以像 ltp.yaml 一样 放在 sh 脚本中 + +对于跑起来一个测试重要的是 完善 params 字段 和 run 字段 ,但对于后期的交互和维护来说 其他的字段也是必不可少的 + +详细可以查看 [编写 Lava-Test 测试定义 1.0 — LAVA 2024.09 文档 --- Writing a Lava-Test Test Definition 1.0 — LAVA 2024.09 documentation](https://docs.lavasoftware.org/lava/writing-tests.html#test-definition-yaml) + +## 一些提示 + +lava会实时检查 device-type 和 job 的状态 ,这些不符合语法 的时候无法正常进行测试,很长一段时间我都以为更新 device-type 需要重启 lava 服务,浪费了很长时间,后来发现不需要,大家在线修改即可。 + +我在整个项目过程中困扰我最多的并不是项目本身,而是我个人工作设备所带来的问题,真的很不推荐大家使用虚拟环境来做 lava 相关的工作。 + +了解 uboot 相关知识可能可以给你带来一些帮助,建议在工作前可以细致的了解下 启动流程相关知识。 \ No newline at end of file diff --git "a/doc/tutorials/ospp-kernelci/doc/\351\205\215\347\275\256jenkins.md" "b/doc/tutorials/ospp-kernelci/doc/\351\205\215\347\275\256jenkins.md" new file mode 100644 index 0000000000000000000000000000000000000000..76d68fe96ace47ef00168b76eba84ded004446a7 --- /dev/null +++ "b/doc/tutorials/ospp-kernelci/doc/\351\205\215\347\275\256jenkins.md" @@ -0,0 +1,889 @@ +# 配置 jenkins + +首先要安装 jenkins ,查看官方文档吧![Jenkins 用户手册](https://www.jenkins.io/zh/doc/) + +安装 jenkins 有多种方式,按照你的需求来 我这边直接使用 jar 包 + +在 Jenkins.war 同级目录下使用 ` java -jar jenkins.war --httpPort=8080` 即可 + +## jenkins 安装插件 + +这里演示如何安装插件 **HTTP Request Plugin** + +![jenkins1](img/jenkins/jenkins1.png) + +![jenkins2](img/jenkins/jenkins2.png) + +进入界面后点击**Available plugins** ,搜索 **HTTP Request Plugin** 点击安装 + +## jenkins 配置 Credentials + +为了便于管理密钥,也为了安全考虑 ,这里要配置 Credentials + +![jenkins1](img/jenkins/jenkins1.png) + +![jenkinsnew1](img/jenkins/jenkinsnew1.png) + +![jenkins5](img/jenkins/jenkins5.png) + +可以看到,有很多种形式,后面我们会配置 Secret text 和 SSH Username with private key + +![jenkins6](img/jenkins/jenkins6.png) + +## jenkins 触发 lava job + +### REST API + +这里使用 REST API 做例子,在主机中输入 + +```shell +curl -d '{"username":"admin", "password":"v"}' -H "Content-Type: application/json" -X POST "http://localhost:8000/api/v0.2/token/" +#可以得到如下结果 +{"token":"adminlavatoken"} +``` + +其实就是使用 curl 向 LAVA API 发送 POST 请求 + +如果你对之前的章节还有印象会发现这个 token 正是 **boards.yaml** 中设置的 + +此外你还可以重新提交一个 job,这里是 job 15,他便会按照 job 15 的定义 重新提交一遍 + +```shell +curl -X POST \ + "http://localhost:8000/api/v0.2/jobs/15/resubmit/" \ + -H "Authorization: Token adminlavatoken" +``` + +他将会返回一串报文 + +```shell +{"message":"job(s) successfully submitted","job_ids":[33]} +``` + +表明 job 的提交情况和重新提交的 job id + +也可以直接提交一个新的 job + +```shell +curl -x "" -v -H "Authorization: Token adminlavatoken" \ + -d '{ + "definition": "{\"device_type\":\"qemu\",\"job_name\":\"your-testjob-name\",\"timeouts\":{\"job\":{\"minutes\":30},\"action\":{\"minutes\":20},\"connection\":{\"minutes\":5}},\"priority\":\"medium\",\"visibility\":\"public\",\"context\":{\"arch\":\"riscv64\",\"machine\":\"virt\",\"guestfs_interface\":\"virtio\",\"extra_options\":[\"-nographic\",\"-smp 4\",\"-m 8G\"]},\"metadata\":{\"format\":\"Lava-Test Test Definition 1.0\",\"name\":\"your-testjob-name\",\"description\":\"Description of the test job\",\"version\":\"1.0\"},\"actions\":[{\"deploy\":{\"timeout\":{\"minutes\":20},\"to\":\"tmpfs\",\"images\":{\"kernel_1\":{\"image_arg\":\"-blockdev node-name=pflash0,driver=file,read-only=on,filename={kernel_1}\",\"url\":\"file:///path/to/kernel1\"}}}}]}" + }' \ + -H "Content-Type: application/json" \ + -X POST "http://127.0.0.1:8000/api/v0.2/jobs/" +``` + +这是它返回的报文 + +```shell +* Trying 127.0.0.1:8000... +* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0) +> POST /api/v0.2/jobs/ HTTP/1.1 +> Host: 127.0.0.1:8000 +> User-Agent: curl/7.81.0 +> Accept: */* +> Authorization: Token adminlavatoken +> Content-Type: application/json +> Content-Length: 784 +> +* Mark bundle as not supporting multiuse +< HTTP/1.1 201 Created +< Date: Mon, 14 Oct 2024 09:50:19 GMT +< Server: gunicorn +< Content-Type: application/json +< Vary: Accept,Cookie +< Allow: GET, POST, HEAD, OPTIONS +< X-Frame-Options: DENY +< Content-Length: 58 +< X-Content-Type-Options: nosniff +< X-XSS-Protection: 1; mode=block +< Referrer-Policy: same-origin +< +* Connection #0 to host 127.0.0.1 left intact +{"message":"job(s) successfully submitted","job_ids":[34]} +``` + +这里你就完成了通过 REST API 查看 job 和 重新提交 job 的工作,当然他做更多是 详细可以查看 https://docs.lavasoftware.org/lava/data-export.html + +### pipeline + +这里给出一个简单的 pipeline + +``` +pipeline { + agent any + + stages { + stage('Fetch Job Status') { + steps { + script { + def jobId = "2" // 替换为实际的 Job ID + def response = httpRequest( + url: "http://127.0.0.1:8000/api/v0.2/jobs/${jobId}", // 获取作业状态 + httpMode: 'GET', + authentication: 'lava-api-token' + ) + echo "Job Status: ${response.content}" + } + } + } + } +} +``` + +从描述可以看出 这是一个获取 lava job status 的 pipeline + +其中 `authentication: 'lava-api-token'` 是 jenkins 中的 Credentials 配置 + +这是根据 REST API 编写的,当然你也可以选择直接在 pipeline 中执行 `sh "curl -d '{"username":"admin", "password":"v"}' -H "Content-Type: application/json" -X POST "http://localhost:8000/api/v0.2/token/" "` + +这是一个触发已有任务的 pipeline + +``` +pipeline { + agent any + + stages { + stage('Resubmit Job') { + steps { + script { + def jobId = "4" // 替换为实际的 Job ID + def token = "adminlavatoken" // 替换为你的 API token + + def response = httpRequest( + url: "http://localhost:8000/api/v0.2/jobs/${jobId}/resubmit/", + httpMode: 'POST', + customHeaders: [[name: 'Authorization', value: "Token ${token}"]] + ) + echo "Response: ${response.content}" + } + } + } + } +} +``` + +可以注意到这里拿 token 直接放在了 pipeline 里,显然是不安全的 后面会解决这个问题 + +可以参考官方文档 [创建您的第一个Pipeline (jenkins.io)](https://www.jenkins.io/zh/doc/pipeline/tour/hello-world/) 来了解如何创建一个 pipeline + +至此,完成了 lava 与 jenkins 使用 pipeline 交互的部分 + +## kernel 源码 与 jenkins + +目前有两种完成 jenkins 的思路,都是使用了 **webhook** + +插件上可以采用 **gitee** 或 **Generic Webhook Trigger** ,安装方式上面有提到,都是类似的。 + +选择 item 方面也可以采用 **自由软件风格项目** 和 **pipeline 项目**两种形式 + +所以这样子搭配 至少有了四种可实现的方法 + +这里会简单阐述方法 先采用 **自由软件风格项目** 和 **gitee** 插件 来做演示 + +### gitee +自由软件风格项目 + +#### gitee 插件 + +安装方面与上面的其他插件方法一致。 + +可以参考 gitee 的官方文档 [Jenkins 插件 - Gitee.com](https://gitee.com/help/articles/4193) ,按着其指示配置 Webhook ,此时点击项目 WebHooks 中的 **测试** + +![jenkins7](img/jenkins/jenkins7.png) + +会有相应的结果,但我这里显示超时,这其实是 gitee 这边测试的 bug ,似乎已经很长时间了,正常你触发的时候是没问题的 + +![jenkins8](img/jenkins/jenkins8.png) + + + +正常 push 代码时是会正常触发的,可以查看 jenkins system log + +(我这里单独把 gitee 的 log 拎了出来) + +![jenkins9](img/jenkins/jenkins9.png) + +可以看到是有正常的信息的 + +到这里你完成了 使用 gitee 插件 捕获 webhook 传来的信息 + +#### 自由软件风格项目 + +**Build Steps** 这部分选择使用 Execute shell ,来让 jenkins 可以直接使用部署其服务的主机的环境。 + +由于之前的工作 ( gitee 插件会根据你的需求,自动更新你所跟踪的 gitee 仓库的状态,我们不用手动拉取),我们已经将 远程仓库的最新状态拉取到本地,由于这种情况下 jenkins 和 lava 位于同一台机器内,可以在编译 Image 后直接使用 REST API,使用 crul 来触发实现准备好的 lava job + +![jenkins11](D:\study\gitee_repositories\RISC-V\doc\tutorials\ospp-kernelci\doc\img\jenkins\jenkins11.png) + + + +### Generic Webhook Trigger + pipeline + +这里我再详细的写出 Generic Webhook Trigger + pipeline 的形式的完整流程 + +#### Generic Webhook 插件 + +首先安装 **Generic Webhook Trigger** 插件 + +![jenkins12](img/jenkins/jenkins12.png) + +#### pipeline 项目 + +创建一个 pipeline 工程 + +![jenkins13](img/jenkins/jenkins13.png) + +在 **Build Triggers** 点击 Generic Webhook Trigger + +![jenkins10](img/jenkins/jenkins10.png) + +只需要设置 token 即可 + +![jenkins14](img/jenkins/jenkins14.png) + +然后配置 对应仓库的 webhook 我这里我给我的 gitee 仓库配置 + +![jenkins15](img/jenkins/jenkins15.png) + +可以手动触发试试 浏览器输入 `你的jenkis地址/generic-webhook-trigger/invoke?token=你的token` + +![jenkins16](img/jenkins/jenkins16.png) + + + +这里是 获取源码 构建 和 触发 lava lab 的 pipeline ,实际上,获取 webhook 这一环境也可使用 pipeline,有兴趣可以自行尝试 + +```pipeline +pipeline { + agent any + environment { + PATH = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin" + } + stages { + stage('Prepare') { + steps { + script { + // 检查 riscv-kernel 目录是否存在 + if (fileExists('riscv-kernel')) { + echo 'riscv-kernel directory exists in OLK. Checking branch...' + dir('riscv-kernel') { + // 获取当前分支 + def currentBranch = sh(script: 'git rev-parse --abbrev-ref HEAD', returnStdout: true).trim() + echo "Current branch is: ${currentBranch}" + + // 检查当前分支是否为 OLK-6.6 + if (currentBranch == 'OLK-6.6') { + echo 'Already on OLK-6.6 branch. Pulling latest changes...' + sh 'git pull' + } else { + echo "Not on OLK-6.6 branch, switching..." + sh "git checkout OLK-6.6" + sh 'git pull' + } + } + } else { + echo 'riscv-kernel directory does not exist. Cloning OLK-6.6 branch...' + // 直接拉取指定分支的代码 + git url: 'https://gitee.com/feifei-fertilizer/riscv-kernel.git', branch: 'OLK-6.6' + } + } + } + } + stage('Build') { + steps { + sh "ls" + dir('riscv-kernel') { + sh "ls" + // 检查 .config 文件是否存在 + script { + if (fileExists('.config')) { + sh "rm .config" + } else { + echo '.config file does not exist, skipping removal.' + } + } + sh "cp arch/riscv/configs/openeuler_defconfig .config" + sh "make " + sh "make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- Image" + sh "cp arch/riscv/boot/Image ~/ospp/2024-large-files/" + } + } + } + stage('Resubmit Job') { + steps { + script { + def jobId = "15" // 替换为实际的 Job ID + def token = "adminlavatoken" // 替换为你的 API token + + def response = httpRequest( + url: "http://localhost:8000/api/v0.2/jobs/${jobId}/resubmit/", + httpMode: 'POST', + customHeaders: [[name: 'Authorization', value: "Token ${token}"]] + ) + echo "Response: ${response.content}" + } + } + } + } +} +``` + +如果想像这里一样 使用 pipeline 触发则需要额外安装 **HTTP Request Plugin** 插件 + +到这里就可以完成 gitee 源码 push , 自动触发 jenkins 构建 kernel 源码, jenkins 再触发 lavajob , 恭喜你。 + +![jenkins20](img/jenkins/jenkins20.png) + +构建过程图 + +![jenkins17](img/jenkins/jenkins17.png) + +![jenkins18](img/jenkins/jenkins18.png) + +## 目前存在的问题 + +可以看到 jenkins 的构建流程,我们已经打通了最基础的 kernel ci 流程,但是仍有许多不完善的地方 + +1. 搭建 kernel ci 会将 jenkins 和 LAVA 部署在多台机器上 +2. 不能把 token 等需要保护的信息暴露在 pipeline 里 +3. 触发 job 举的例子是触发 LAVA 中已存在的 job,但既然是 CI 要考虑初次触发job的情况 + +# 更完善的解决方案 + +## 解决 token 暴露的问题 + +配置 Credentials,上面有介绍过这部分内容 + +![jenkinsnew2](img/jenkins/jenkinsnew2.png) + +![jenkinsnew3](img/jenkins/jenkinsnew3.png) + + + +这里要注意的是不要配置成 Admin credentials 这是管理员的凭据 ,而要配置 **Manage Jenkins 中的 credentials**。 + +此时你就可以把 pipeline 修改为 + +```pipeline +pipeline { + agent any + stages { + stage('Resubmit Job') { + steps { + script { + def jobId = "4" // 替换为实际的 Job ID + + // 使用 withCredentials 确保凭据被正确加载 + withCredentials([string(credentialsId: 'lava-api-token', variable: 'TOKEN')]) { + def response = httpRequest( + url: "http://localhost:8000/api/v0.2/jobs/${jobId}/resubmit/", + httpMode: 'POST', + customHeaders: [[name: 'Authorization', value: "Token ${TOKEN}"]] + ) + echo "Response: ${response.content}" + } + } + } + } + } +} +``` + +[string(credentialsId: 'lava-api-token', variable: 'TOKEN')] 是 Jenkins Pipeline 的一个参数列表 + +string(...):指定凭据的类型为字符串 + +lava-api-token 对应的是上面配置的 secret text 的 credentials id , + +variable:'TOKEN':定义了在 Pipeline 中使用该凭据时的环境变量名称,凭据的值将被赋给这个变量。 + + + +此时 jenkins log 中 便不会显示 token 的明文信息 + +![jenkinsnew4](img/jenkins/jenkinsnew4.png) + +## 解决 image 构建问题 + +先罗列需要做的事 + +1. 搭建 jenkins 的机器(机器A) 得到 webhook 信息 +2. 传递该信息,使负责编译源码的机器(机器B)更新代码并完成编译 +3. 机器B 将编译好的内容传递给 lava 宿主机(机器C) +4. 机器C 完成 lava 测试 + +我们之前 A B C 均为同一台机器,不用考虑网络,权限等问题 + +这里我考虑三台机器的关系如下 + +1. A -> B -> C +2. A <-> B and B -> C + +第一种适合简单的情况,第二种则适用于复杂的场景. + +下面给出怎么做 + +### 安装 SSH Agent 插件 + +然后配置 **ssh credentials** + +这里给出示意图 + +![jenkinsnew5](img/jenkins/jenkinsnew5.png) + +在 ssh 连接的服务器上配置好你的公钥即可,下面是一个 使用 ssh credentials pipeline 的基础模板 + +```pipeline +pipeline { + agent any + + stages { + stage('Connect to Remote Machine') { + steps { + script { + sshagent(['my-ssh-credentials']) { // 替换为你的凭据 ID + sh 'ssh username@ip "command"' + } + } + } + } + } +} +``` + +这里给出一部分 ssh 连接后的指令,这里涉及到的是源码的更新 + +```pipeline +pipeline { + agent any + + stages { + stage('CHECK KERNEL EXIST') { + steps { + script { + sshagent(['my-ssh-credentials']) { // 替换为你的凭据 ID + def command = ''' + if ls ~/build | grep -q 'riscv-kernel'; then + echo "Found 'riscv-kernel' in ~/build." + else + echo "'riscv-kernel' not found in ~/build. Cloning repository..." + git clone https://gitee.com/feifei-fertilizer/riscv-kernel.git ~/build + fi + + cd ~/build/riscv-kernel + + # 检查当前分支 + current_branch=$(git rev-parse --abbrev-ref HEAD) + if [ "$current_branch" = "OLK-6.6" ]; then + echo "Currently on branch 'OLK-6.6'." + # 在这里添加处理分支在该分支上的代码 + else + echo "Not on branch 'OLK-6.6', currently on branch '$current_branch'. Switching to 'OLK-6.6'..." + git checkout OLK-6.6 + fi + git pull + ''' + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 '${command}'" + } + } + } + } + } +} +``` + +开始构建 , 这里 ssh 连接到远程构建的机器 使用其环境开始构建,我选择把 更新源码 和 编译 kernel 分为两个 stage ,这样哪一环出了问题可以更好的定位。这里检测了 config 文件是否存在 以及使用什么工具链。 + +```pipeline +pipeline { + agent any + + stages { + stage('COMPILE THE KERNEL') { + steps { + script { + sshagent(['my-ssh-credentials']) { // 替换为你的凭据 ID + def command = ''' + cd ~/build/riscv-kernel + if [ -f ~/build/riscv-kernel/.config ]; then + echo ".config file exists." + rm ~/build/riscv-kernel/.config + else + echo ".config file does not exist." + fi + cp ~/build/riscv-kernel/arch/riscv/configs/openeuler_defconfig ~/build/riscv-kernel/.config + make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- Image + ''' + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 '${command}'" + } + } + } + } + } +} +``` + +文件传输 ,有几种思路,我这里使用了 scp,毕竟之前我们一直在使用 ssh ,你也可以把文件传输到服务器上,或 git 仓库,总之 lava 服务器能得到就行 + +```pipeline +pipeline { + agent any + + stages { + stage('COMPILE THE KERNEL') { + steps { + script { + sshagent(['my-ssh-credentials']) { // 替换为你的凭据 ID + def command = '''l + if [ -f ~/build/riscv-kernel/arch/riscv/boot/Image ]; then + echo "Image file exists." + else + echo ".config file does not exist." + fi + scp ~/build/riscv-kernel/arch/riscv/boot/Image feifei@192.168.0.149:~/ospp/2024ospp-large-files/new + ''' + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 '${command}'" + } + } + } + } + } +} +``` + +## 解决首次触发问题 + +我们之前的 ci 方案是重新提交了已有的 job,无法解决首次触发的问题 + +lava 官方提供了三种触发方式 分别是 XML-RPC , Web , 命令行使用 lavacli 命令 (其实还有 REST API) + +可以查看 [提交您的第一份工作 — LAVA 2024.09 文档 --- Submitting your first job — LAVA 2024.09 documentation (lavasoftware.org)](https://docs.lavasoftware.org/lava/first-job.html#index-2) + +之前我们的方案就是采用了 REST API ,上面也提过可以做到,但我们接下来的方案使用的是 lavacli 原因有一下几点 + +1. lavacli 提供的是 yaml 文件,可以拿着 job 模板直接提交,服务端也可以比较方便管理 job +2. 使用 REST API 提交 ,lava 会进行很严格的格式检测 ,这让我们提供的测试定义被压缩在一行,可读性极差,而且本人在提交时经常因为格式问题不成功 + +下面的 pipeline 实现了 判断有没有 同名的 job ,有的话就重新提交该 job,没有的话就通过 lavacli 提交定义 + +```pipeline +pipeline { + agent any + + stages { + stage('COMPILE THE KERNEL') { + steps { + script { + sshagent(['my-ssh-credentials']) { + withCredentials([string(credentialsId: 'lava-api-token', variable: 'TOKEN')]) { + def LAVA_URI = "http://admin:${TOKEN}@192.168.0.149:8000/RPC2/" + def JOB_NAME = "qemu-oerv-24.03-smoke-test" + def JOB_Path = "~/ospp/example/job/qemu/qemu-oerv-24.03-smoke-test.yaml" + def command = """ + # 列出作业并检查 + JOB_INFO=\$(lavacli --uri "$LAVA_URI" jobs list | grep "$JOB_NAME") + JOB_ID=\$(echo "\$JOB_INFO" | awk "{print \\\$2}" | cut -d':' -f1 | head -n 1) + if [ -n "\$JOB_ID" ]; then + echo "Lately Job ID: \$JOB_ID." + curl -X POST \ + "http://192.168.0.149:8000/api/v0.2/jobs/\$JOB_ID/resubmit/" \ + -H "Authorization: Token ${TOKEN}" + else + echo "Job '$JOB_NAME' does not exist." + lavacli --uri "$LAVA_URI" jobs submit $JOB_Path + fi + + """ + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 ${command}" + } + } + } + } + } + } +} +``` + +当然 这个解决方法目前也存在一些问题 + +这个查看的只是最近作业中有没有重名 job ,考虑到大型的 lava 项目 job id 会以万为单位计算,这显然不是特别好的解决方案, 而且当 job 名称(取决于 job 中的 job name 字段 ) 与提供的 yaml 文件名称不完全一致,也无法检测出 + +不过好在检测不出也能提供定义,进而进行测试 + +我认为用 lavacli 的方式来管理每一个 job 会比较好,这样每个 job 在服务器中都有一个对应的 yaml 文件. + +## 解决问题并压缩到一个 pipeline 中 + +```pipeline +pipeline { + agent any + + stages { + stage('CHECK KERNEL EXIST') { + steps { + script { + sshagent(['my-ssh-credentials']) { // 替换为你的凭据 ID + def command = ''' + if ls ~/build | grep -q 'riscv-kernel'; then + echo "Found 'riscv-kernel' in ~/build." + else + echo "'riscv-kernel' not found in ~/build. Cloning repository..." + git clone https://gitee.com/feifei-fertilizer/riscv-kernel.git ~/build + fi + + cd ~/build/riscv-kernel + + # 检查当前分支 + current_branch=$(git rev-parse --abbrev-ref HEAD) + if [ "$current_branch" = "OLK-6.6" ]; then + echo "Currently on branch 'OLK-6.6'." + # 在这里添加处理分支在该分支上的代码 + else + echo "Not on branch 'OLK-6.6', currently on branch '$current_branch'. Switching to 'OLK-6.6'..." + git checkout OLK-6.6 + fi + git pull + ''' + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 '${command}'" + } + } + } + } + stage('COMPILE THE KERNEL') { + steps { + script { + sshagent(['my-ssh-credentials']) { // 替换为你的凭据 ID + def command = ''' + cd ~/build/riscv-kernel + if [ -f ~/build/riscv-kernel/.config ]; then + echo ".config file exists." + rm ~/build/riscv-kernel/.config + else + echo ".config file does not exist." + fi + cp ~/build/riscv-kernel/arch/riscv/configs/openeuler_defconfig ~/build/riscv-kernel/.config + make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- Image + ''' + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 '${command}'" + } + } + } + } + stage('TRANSFER THE KERNEL') { + steps { + script { + sshagent(['my-ssh-credentials']) { // 替换为你的凭据 ID + def command = ''' + if [ -f ~/build/riscv-kernel/arch/riscv/boot/Image ]; then + echo "Image file exists." + else + echo "Image does not exist." + fi + scp ~/build/riscv-kernel/arch/riscv/boot/Image feifei@192.168.0.149:~/ospp/2024ospp-large-files/new + ''' + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 '${command}'" + } + } + } + } + stage('TRIGGER LAVA JOB') { + steps { + script { + sshagent(['my-ssh-credentials']) { + withCredentials([string(credentialsId: 'lava-api-token', variable: 'TOKEN')]) { + def LAVA_URI = "http://admin:${TOKEN}@192.168.0.149:8000/RPC2/" + def JOB_NAME = "qemu-oerv-24.03-smoke-test" + def JOB_Path = "~/ospp/example/job/qemu/qemu-oerv-24.03-smoke-test.yaml" + def command = """ + # 列出作业并检查 + JOB_INFO=\$(lavacli --uri "$LAVA_URI" jobs list | grep "$JOB_NAME") + JOB_ID=\$(echo "\$JOB_INFO" | awk "{print \\\$2}" | cut -d':' -f1 | head -n 1) + if [ -n "\$JOB_ID" ]; then + echo "Lately Job ID: \$JOB_ID." + curl -X POST \ + "http://192.168.0.149:8000/api/v0.2/jobs/15/resubmit/" \ + -H "Authorization: Token ${TOKEN}" + else + echo "Job '$JOB_NAME' does not exist." + lavacli --uri "$LAVA_URI" jobs submit $JOB_Path + fi + + """ + // 使用单个 SSH 连接执行全部命令 + sh "ssh feifei@192.168.0.149 ${command}" + } + } + } + } + } + } +} +``` + +**查看结果** + +完成 kernel 编译 并发送 + +![jenkinsnew6](img/jenkins/jenkinsnew6.png) + +触发 job + +![jenkinsnew7](img/jenkins/jenkinsnew7.png) + +lava 测试结果 + +![jenkinsnew8](img/jenkins/jenkinsnew8.png) + +![jenkinsnew9](img/jenkins/jenkinsnew9.png) + +在 jenkins 端查看结果 + +![jenkinsnew10](img/jenkins/jenkinsnew10.png) + +完成 + +## 使用 jenkins nodes + +经过老师的指导,了解到 jenkins 可以添加多个 node ,实在是很方便 + +还是那几台机器 但是不用 在每个 stage 里手动连接, 只需要使用 `node('name') `即可使用配置好的机器 + +下面展示如何配置 node + +![jenkinsnew11](img/jenkins/jenkinsnew11.png) + +按照下面的方式填写 + +启动方式选择 Launch agents via SSH ,credentials 选择 feifei ,这个是前面提过的配置的 ssh credentials + +![jenkinsnew12](img/jenkins/jenkinsnew12.png) + +可以看到我们 nodes 列表 ,目前节点的状态 + +注意使用 node 管理的机器需要安装有 java 17,否则会报错 ,这是之前直接使用 ssh 连接所不需要的 + +![jenkinsnew13](img/jenkins/jenkinsnew13.png) + +下面是使用 node 的版本 ,可以更直观的看出都用了哪个节点 + +```pipeline +pipeline { + agent none // 不在整个 pipeline 级别上指定 agent + stages { + stage('CHECK KERNEL EXIST') { + steps { + script { + node('kernel') { // 指定使用标签为 'kernel' 的节点 + sh ''' + if ls ~/build | grep -q 'riscv-kernel'; then + echo "Found 'riscv-kernel' in ~/build." + else + echo "'riscv-kernel' not found in ~/build. Cloning repository..." + git clone https://gitee.com/feifei-fertilizer/riscv-kernel.git ~/build + fi + + cd ~/build/riscv-kernel + + # 检查当前分支 + current_branch=$(git rev-parse --abbrev-ref HEAD) + if [ "$current_branch" = "OLK-6.6" ]; then + echo "Currently on branch 'OLK-6.6'." + # 在这里添加处理分支在该分支上的代码 + else + echo "Not on branch 'OLK-6.6', currently on branch '$current_branch'. Switching to 'OLK-6.6'..." + git checkout OLK-6.6 + fi + git pull + ''' + } + } + } + } + stage('COMPILE THE KERNEL') { + steps { + script { + node('kernel') { // 使用标签为 'kernel' 的节点 + sh ''' + cd riscv-kernel + if [ -f ~.config ]; then + echo ".config file exists." + rm .config + else + echo ".config file does not exist." + fi + cp ./arch/riscv/configs/openeuler_defconfig .config + ''' + } + } + } + } + stage('TRANSFER THE KERNEL') { + steps { + script { + node('kernel') { // 再次使用标签 'kernel' + sh ''' + if [ -d ./oerv-24.03-kernel-image ]; then + echo "oerv-24.03-kernel-image exists." + else + echo "oerv-24.03-kernel-image does not exist." + git clone git@gitee.com:feifei-fertilizer/oerv-24.03-kernel-image.git + fi + cp ./riscv-kernel/arch/riscv/boot/Image ./oerv-24.03-kernel-image cd oerv-24.03-kernel-image + git commit -m "$(date +"%Y-%m-%d %H:%M:%S")" + git push + ''' + } + } + } + } + stage('TRIGGER LAVA JOB') { + steps { + script { + node('lava') { // 使用标签 'lava' + withCredentials([string(credentialsId: 'lava-api-token', variable: 'TOKEN')]) { + def LAVA_URI = "http://admin:${TOKEN}@192.168.0.149:8000/RPC2/" + def JOB_NAME = "qemu-oerv-24.03-smoke-test" + def JOB_Path = "~/ospp/example/job/qemu/qemu-oerv-24.03-smoke-test.yaml" + sh """ + # 列出作业并检查 + if [ -d ./oerv-24.03-kernel-image ]; then + echo "oerv-24.03-kernel-image exists." + else + echo "oerv-24.03-kernel-image does not exist." + git clone git@gitee.com:feifei-fertilizer/oerv-24.03-kernel-image.git + fi + JOB_INFO=\$(lavacli --uri "$LAVA_URI" jobs list | grep "$JOB_NAME") + JOB_ID=\$(echo "\$JOB_INFO" | awk "{print \\\$2}" | cut -d':' -f1 | head -n 1) + if [ -n "\$JOB_ID" ]; then + echo "Lately Job ID: \$JOB_ID." + curl -X POST \ + "http://192.168.0.149:8000/api/v0.2/jobs/15/resubmit/" \ + -H "Authorization: Token ${TOKEN}" + else + echo "Job '$JOB_NAME' does not exist." + lavacli --uri "$LAVA_URI" jobs submit $JOB_Path + fi + """ + } + } + } + } + } + } +} +``` + +这次没有再用 scp 传文件,而是在编译完 Image 后上传到远程仓库中,再让 `lava` 更新远程仓库内容到本地,以此获得 Image + +这里套用了之前的命令行 ,看着很臃肿,你也可以用 try catch 等方式来优化一些细节 + +结果如下 + +![jenkinsnew15](img/jenkins/jenkinsnew15.png)![jenkinsnew14](img/jenkins/jenkinsnew14.png) diff --git a/doc/tutorials/ospp-kernelci/jobs/Lip4a.yaml b/doc/tutorials/ospp-kernelci/jobs/Lip4a.yaml new file mode 100755 index 0000000000000000000000000000000000000000..c43442319ed3126133f5e41ce9e827536622d65f --- /dev/null +++ b/doc/tutorials/ospp-kernelci/jobs/Lip4a.yaml @@ -0,0 +1,85 @@ +device_type: Lpi4a +job_name: +context: + boot_character_delay: 1000 + extra_nfsroot_args: ",nolock,nfsvers=3" +timeouts: + job: + minutes: 301 + action: + minutes: 300 + actions: + power-off: + seconds: 30 +priority: medium +visibility: public +metadata: + # please change these fields when modifying this job for your own tests. + format: + name: + description: "" + version: "1.0" +# ACTION_BLOCK +actions: +# DEPLOY_BLOCK +- deploy: + timeout: + minutes: 20 + to: tftp + kernel: + url: file:///home/2024ospp-large-files/Image + type: image + dtb: + url: file:///home/2024ospp-large-files/licheepi4a/thead/th1520-lichee-pi-4a.dtb + nfsrootfs: + url: file:///home/2024ospp-large-files/openeuler-rootfs.tar.gz + compression: gz +# BOOT_BLOCK +- boot: + timeout: + minutes: 20 + method: u-boot + commands: nfs + soft_reboot: + - root + - openEuler + - reboot + - The system will reboot now! + prompts: + - '[root@openeuler-riscv64 ~]#' + auto_login: + login_prompt: "(.*)openeuler-riscv64 login:(.*)" + username: root + password_prompt: "Password:" + password: openEuler12#$ +# TEST_BLOCK +- test: + timeout: + minutes: 240 + definitions: + - repository: + metadata: + format: Lava-Test Test Definition 1.0 + name: install-dependency-package + run: + steps: + - yum install -y gcc automake + - df -h + from: inline + name: install-dependency-package-inline + path: inline/install-dependency-package.yaml + - repository: https://github.com/Linaro/test-definitions.git + from: git + path: automated/linux/ltp/ltp.yaml + parameters: + TST_CMDFILES: syscalls + SKIPFILE: skipfile-lkft.yaml + BOARD: qemu + BRANCH: master + ENVIRONMENT: production + TIMEOUT_MULTIPLIER: '30' + ROOT_PASSWD: openEuler12#$ + BUILD_FROM_TAR: true + LTP_VERSION: 20240524 + TEST_DIR: /root/ltp + name: ltp-syscalls-tests \ No newline at end of file diff --git a/doc/tutorials/ospp-kernelci/jobs/qemu.yaml b/doc/tutorials/ospp-kernelci/jobs/qemu.yaml new file mode 100755 index 0000000000000000000000000000000000000000..0db3b478c22ce068803f5f0f852b992f66421951 --- /dev/null +++ b/doc/tutorials/ospp-kernelci/jobs/qemu.yaml @@ -0,0 +1,91 @@ +# Your first LAVA JOB definition for an riscv_64 QEMU +device_type: qemu +job_name: +timeouts: + job: + minutes: 660 + action: + minutes: 650 + connection: + minutes: 5 +priority: medium +visibility: public +# context allows specific values to be overridden or included +context: + # tell the qemu template which architecture is being tested + # the template uses that to ensure that qemu-system-riscv64 is executed. + arch: riscv64 + machine: virt + guestfs_interface: virtio + extra_options: + - -machine virt + - -nographic + - -smp 16 + - -m 16G + - -device virtio-blk-device,drive=hd0 + - -append "root=/dev/vda rw console=ttyS0 selinux=0" + - -device virtio-net-device,netdev=usernet + - -netdev user,id=usernet,hostfwd=tcp::10008-:22 +metadata: + # please change these fields when modifying this job for your own tests. + format: + name: + description: "" + version: "1.0" +# ACTION_BLOCK +actions: +# DEPLOY_BLOCK +- deploy: + timeout: + minutes: 20 + to: tmpfs + images: + kernel: + image_arg: -kernel {kernel} + url: file:///home/2024ospp-large-files/Image + rootfs: + image_arg: -drive file={rootfs},format=raw,id=hd0 + url: file:///home/2024ospp-large-files/openeuler-rootfs.img +# BOOT_BLOCK +- boot: + timeout: + minutes: 20 + method: qemu + media: tmpfs + prompts: ["root@openeuler-riscv64"] + auto_login: + login_prompt: "openeuler-riscv64 login:" + username: root + password_prompt: "Password:" + password: openEuler12#$ +# TEST_BLOCK +- test: + timeout: + minutes: 240 + definitions: + - repository: + metadata: + format: Lava-Test Test Definition 1.0 + name: install-dependency-package + run: + steps: + - yum install -y gcc automake + - df -h + from: inline + name: install-dependency-package-inline + path: inline/install-dependency-package.yaml + - repository: https://github.com/Linaro/test-definitions.git + from: git + path: automated/linux/ltp/ltp.yaml + parameters: + TST_CMDFILES: syscalls + SKIPFILE: skipfile-lkft.yaml + BOARD: qemu + BRANCH: master + ENVIRONMENT: production + TIMEOUT_MULTIPLIER: '30' + ROOT_PASSWD: openEuler12#$ + BUILD_FROM_TAR: true + LTP_VERSION: 20240524 + TEST_DIR: /root/ltp + name: ltp-syscalls-tests \ No newline at end of file diff --git a/doc/tutorials/ospp-kernelci/power-control/README.md b/doc/tutorials/ospp-kernelci/power-control/README.md new file mode 100755 index 0000000000000000000000000000000000000000..00bb0741bca21d939f85c9b8a77cdf2f0c53fc6b --- /dev/null +++ b/doc/tutorials/ospp-kernelci/power-control/README.md @@ -0,0 +1,24 @@ +电源控制有很多种方式,我这里使用的是继电器,有的开发板支持深度睡眠也可以直接通过引脚控制电源开关 + +这里给出两种方式的 c 代码 + +[通过 mqtt ](./mqtt-esp8266.c) + +在同一局域网下可以使用以下命令控制继电器 进而控制设备电源 + +```shell +mosquitto_pub -h 192.168.0.158 -t "device/power" -m "RESET" +mosquitto_pub -h 192.168.0.158 -t "device/power" -m "ON" +mosquitto_pub -h 192.168.0.158 -t "device/power" -m "OFF" +``` + +[通过串口](./serialport-arduino-uno3.c) + +通过让 slave 通过串口通信访问 arduino 开发板 控制继电器 进而控制设备电源 + +```shell +(echo "OFF"; sleep 1; echo "ON") | telnet 192.168.0.158 20001 +(echo "ON") | telnet 192.168.0.158 20001 +(echo "OFF") | telnet 192.168.0.158 20001 +``` + diff --git a/doc/tutorials/ospp-kernelci/power-control/mqtt-esp8266.c b/doc/tutorials/ospp-kernelci/power-control/mqtt-esp8266.c new file mode 100755 index 0000000000000000000000000000000000000000..1e66a924b0f9618a7d26af6b586c1725c8be73a6 --- /dev/null +++ b/doc/tutorials/ospp-kernelci/power-control/mqtt-esp8266.c @@ -0,0 +1,82 @@ +#include +#include + +// WiFi 配置 +const char* ssid = "feifei_cpe"; // 替换为你的 WiFi SSID +const char* password = "feifei0827"; // 替换为你的 WiFi 密码 + +// MQTT 服务器配置 +const char* mqtt_server = "192.168.0.158"; // 替换为您的 MQTT 服务器地址 +const char* mqtt_topic = "device/power"; // 控制主题 + +// GPIO 引脚 +const int relayPin = 4; // 继电器控制引脚 + +WiFiClient espClient; +PubSubClient client(espClient); + +void setup() { + Serial.begin(115200); + pinMode(relayPin, OUTPUT); + digitalWrite(relayPin, LOW); // 初始状态关闭继电器 + + // 连接到 WiFi + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(1000); + Serial.println("连接中..."); + } + Serial.println("WiFi 连接成功"); + + // 设置 MQTT 服务器 + client.setServer(mqtt_server, 1883); + client.setCallback(callback); + + // 连接到 MQTT + reconnect(); +} + +void loop() { + if (!client.connected()) { + reconnect(); + } + client.loop(); +} + +// MQTT 消息回调函数 +void callback(char* topic, byte* payload, unsigned int length) { + String message; + for (int i = 0; i < length; i++) { + message += (char)payload[i]; + } + + if (message == "ON") { + digitalWrite(relayPin, HIGH); // 打开继电器 + Serial.println("电源已打开"); + } else if (message == "OFF") { + digitalWrite(relayPin, LOW); // 关闭继电器 + Serial.println("电源已关闭"); + } else if (message == "RESET") { + Serial.println("重置设备..."); + digitalWrite(relayPin, LOW); // 关闭继电器 + Serial.println("电源已关闭"); + delay(500); + digitalWrite(relayPin, HIGH); // 打开继电器 + Serial.println("电源已打开"); + } +} + +// 连接到 MQTT 服务器 +void reconnect() { + while (!client.connected()) { + Serial.print("连接到 MQTT..."); + if (client.connect("ESP8266Client")) { + Serial.println("连接成功"); + client.subscribe(mqtt_topic); + } else { + Serial.print("失败,状态码="); + Serial.print(client.state()); + delay(2000); + } + } +} \ No newline at end of file diff --git a/doc/tutorials/ospp-kernelci/power-control/serialport-arduino-uno3.c b/doc/tutorials/ospp-kernelci/power-control/serialport-arduino-uno3.c new file mode 100755 index 0000000000000000000000000000000000000000..d56a2ed40da3317beea99cd1063182b2b839bfeb --- /dev/null +++ b/doc/tutorials/ospp-kernelci/power-control/serialport-arduino-uno3.c @@ -0,0 +1,21 @@ +// 定义继电器连接的引脚 +const int relayPin = 4; + +void setup() { + // 初始化继电器引脚为输出模式 + pinMode(relayPin, OUTPUT); + // 初始状态为关闭继电器 + digitalWrite(relayPin, LOW); +} + +void loop() { + // 打开继电器 + digitalWrite(relayPin, HIGH); + Serial.println("Relay ON"); + delay(1000); // 延时1秒 + + // 关闭继电器 + digitalWrite(relayPin, LOW); + Serial.println("Relay OFF"); + delay(1000); // 延时1秒 +} \ No newline at end of file diff --git a/doc/tutorials/ospp-kernelci/test-definitions/kselftest/keselftest.yaml b/doc/tutorials/ospp-kernelci/test-definitions/kselftest/keselftest.yaml new file mode 100755 index 0000000000000000000000000000000000000000..8249616ac752f47de9545ab393e9c817694105ac --- /dev/null +++ b/doc/tutorials/ospp-kernelci/test-definitions/kselftest/keselftest.yaml @@ -0,0 +1,21 @@ +metadata: + name: kselftest + format: "Lava-Test Test Definition 1.0" + description: "Run kselftest test suite on openEuler" + os: + - openEuler + scope: + - functional + devices: + - all +run: + steps: + - yum install -y git make gcc flex bison clang + - df -h + - cd /root + - git clone https://gitee.com/feifei-fertilizer/riscv-kernel.git + - cd riscv-kerner.git + - git checkout OLK-6.6 + - make defconfig + - make -C tools/testing/selftests + - make -C tools/testing/selftests run_tests \ No newline at end of file diff --git a/doc/tutorials/ospp-kernelci/test-definitions/ltp/ltp.yaml b/doc/tutorials/ospp-kernelci/test-definitions/ltp/ltp.yaml new file mode 100755 index 0000000000000000000000000000000000000000..4f70958ba84fb8f7867f85b4c610201879aaafe9 --- /dev/null +++ b/doc/tutorials/ospp-kernelci/test-definitions/ltp/ltp.yaml @@ -0,0 +1,26 @@ +metadata: + name: ltp + format: "Lava-Test Test Definition 1.0" + description: "Run ltp test suite on openEuler" + os: + - openEuler + scope: + - functional + devices: + - all +run: + steps: + - yum install -y gcc automake + - df -h + - wget -P /root https://github.com/linux-test-project/ltp/releases/download/20240524/ltp-full-20240524.tar.xz + - cd /root + - tar -xJf ltp-full-20240524.tar.xz + - df -h + - cd ltp-full-20240524 + - make autotools + - ./configure + - make -j $(nproc) + - df -h + - make install + - cd /opt/ltp + - ./runltp \ No newline at end of file