PageSourceSearch

https://milkv.io/assets/js/ff1b3682.c87a6b5e.js

js milkv.io collected 2026-09-24 19:33:52 UTC 53,497 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkmilkv_website=self.webpackChunkmilkv_website||[]).push([[2988],{37324:(e,o,i)=>{i.r(o),i.d(o,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>r});var n=i(85893),s=i(11151);const d={sidebar_label:"Buildroot SDK",sidebar_position:40},l="Introduction",t={id:"duo/getting-started/buildroot-sdk",title:"Introduction",description:"The default SDK for the Duo series boards is built based on buildroot and is used to generate Duo firmware. Currently, the SDK has two versions: V1 and V2.",source:"@site/docs/duo/getting-started/buildroot-sdk.md",sourceDirName:"duo/getting-started",slug:"/duo/getting-started/buildroot-sdk",permalink:"/docs/duo/getting-started/buildroot-sdk",draft:!1,unlisted:!1,editUrl:"https://github.com/milk-v/milkv.io/edit/main/docs/duo/getting-started/buildroot-sdk.md",tags:[],version:"current",sidebarPosition:40,frontMatter:{sidebar_label:"Buildroot SDK",sidebar_position:40},sidebar:"duo",previous:{title:"Setting Up",permalink:"/docs/duo/getting-started/setup"},next:{title:"RTOS Core",permalink:"/docs/duo/getting-started/rtoscore"}},c={},r=[{value:"Buildroot SDK V1",id:"buildroot-sdk-v1",level:2},{value:"Buildroot SDK V2",id:"buildroot-sdk-v2",level:2},{value:"1. Compiled using Ubuntu 22.04",id:"1-compiled-using-ubuntu-2204",level:2}
1,{value:"Packages to be installed",id:"packages-to-be-installed",level:3},{value:"Get SDK Source Code",id:"get-sdk-source-code",level:3},{value:"1). One-click Compilation",id:"1-one-click-compilation",level:3},{value:"2). Step-by-step Compilation",id:"2-step-by-step-compilation",level:3},{value:"2. Compiled using Docker",id:"2-compiled-using-docker",level:2},{value:"Pull SDK code on Linux host",id:"pull-sdk-code-on-linux-host",level:3},{value:"Enter the SDK code directory",id:"enter-the-sdk-code-directory",level:3},{value:"Pull the Docker image and run",id:"pull-the-docker-image-and-run",level:3},{value:"1). One-click compilation using Docker",id:"1-one-click-compilation-using-docker",level:3},{value:"2). Compile step by step using Docker",id:"2-compile-step-by-step-using-docker",level:3},{value:"Stop Docker",id:"stop-docker",level:3},{value:"3. Other compilation considerations",id:"3-other-compilation-considerations",level:2},{value:"cmake version",id:"cmake-version",level:3},{value:"Compiling with Windows Linux Subsystem (WSL)",id:"compiling-with-windows-linux-subsystem-wsl",level:3},{value:"4. Add application packages",id:"4-add-application-packages",level:2},{value:"Enable commands in Busybox",id:"enable-commands-in-busybox",level:3},{value:"Configure application packages preset in Buildroot",id:"configure-application-packages-preset-in-buildroot",level:3},{value:"Add your own application package",id:"add-your-own-application-package",level:3},{value:"5. Delete application packages",id:"5-delete-application-packages",level:2},{value:"6. Frequently Asked Questions",id:"6-frequently-asked-questions",level:2},{value:"Buildroot troubleshooting method",id:"buildroot-troubleshooting-method",level:3},{value:"Buildroot package download failed",id:"buildroot-package-download-failed",level:3}];function a(e){const o={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,s.a)(),...e.components},{Image:i}=o;return i||function(e,o){throw new Error("Expected "+(o?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Image",!0),(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.h1,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(o.p,{children:"The default SDK for the Duo series boards is built based on buildroot and is used to generate Duo firmware. Currently, the SDK has two versions: V1 and V2."}),"\n",(0,n.jsx)(o.admonition,{type:"tip",children:(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsx)(o.li,{children:"SDK V1 only supports RISC-V core. (This version is recommended for Duo 64M)"}),"\n",(0,n.jsx)(o.li,{children:"SDK V2 supports both RISC-V and ARM cores. (This version is recommended for Duo256M and DuoS)"}),"\n"]})}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.em,{children:"It is recommended that Duo 64M use the V1 version of the SDK, mainly because its memory is small. The related AI applications in the V2 version of the SDK cannot currently run normally in Duo 64M."})}),"\n",(0,n.jsx)(o.h2,{id:"buildroot-sdk-v1",children:"Buildroot SDK V1"}),"\n",(0,n.jsx)(o.p,{children:"The SDK mainly contains the following parts:"}),"\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsx)(o.li,{children:"u-boot: 2021.10"}),"\n",(0,n.jsx)(o.li,{children:"linux kernel: 5.10.4"}),"\n",(0,n.jsx)(o.li,{children:"buildroot: 2021.05"}),"\n",(0,n.jsx)(o.li,{children:"opensbi: 89182b2"}),"\n"]}),"\n",(0,n.jsxs)(o.p,{children:["Source code: ",(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk",children:"https://github.com/milkv-duo/duo-buildroot-sdk"})]}),"\n",(0,n.jsx)(o.p,{children:"SDK Directory Structure:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-text",children:"\u251c\u2500\u2500 build                compilation scripts and board configs\n\u251c\u2500\u2500 build.sh             one-click compilation script\n\u251c\u2500\u2500 buildroot-2021.05    buildroot source code\n\u251c\u2500\u2500 freertos             freertos system\n\u251c\u2500\u2500 fsbl                 fsbl firmware in prebuilt form\n\u251c\u2500\u2500 install              temporary images stored here\n\u251c\u2500\u2500 isp_tuning           camera effect parameters\n\u251c\u2500\u2500 linux_5.10           linux kernel\n\u251c\u2500\u2500 middleware           self
1-developed multimedia framework\n\u251c\u2500\u2500 device               configuration files for milkv\n\u251c\u2500\u2500 opensbi              opensbi library\n\u251c\u2500\u2500 out                  image generated by Milk-V\n\u251c\u2500\u2500 ramdisk              prebuilt ramdisk\n\u2514\u2500\u2500 u-boot-2021.10       u-boot source code\n"})}),"\n",(0,n.jsx)(o.h2,{id:"buildroot-sdk-v2",children:"Buildroot SDK V2"}),"\n",(0,n.jsx)(o.p,{children:"The SDK mainly contains the following parts:"}),"\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsx)(o.li,{children:"u-boot: 2021.10"}),"\n",(0,n.jsx)(o.li,{children:"linux kernel: 5.10.4"}),"\n",(0,n.jsx)(o.li,{children:"buildroot: 2025.02"}),"\n",(0,n.jsx)(o.li,{children:"opensbi: 89182b2"}),"\n"]}),"\n",(0,n.jsxs)(o.p,{children:["Source code: ",(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk-v2",children:"https://github.com/milkv-duo/duo-buildroot-sdk-v2"})]}),"\n",(0,n.jsx)(o.p,{children:"Stable branches: main"}),"\n",(0,n.jsx)(o.p,{children:"SDK Directory Structure:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-text",children:"\u251c\u2500\u2500 build                compilation scripts and board configs\n\u251c\u2500\u2500 build.sh             one-click compilation script\n\u251c\u2500\u2500 buildroot            buildroot source code\n\u251c\u2500\u2500 cvi_mpi              sophgo multimedia framework\n\u251c\u2500\u2500 device               configuration files for milkv\n\u251c\u2500\u2500 freertos             freertos system\n\u251c\u2500\u2500 fsbl                 fsbl firmware in prebuilt form\n\u251c\u2500\u2500 install              temporary images stored here\n\u251c\u2500\u2500 isp_tuning           camera effect parameters\n\u251c\u2500\u2500 linux_5.10           linux kernel\n\u251c\u2500\u2500 osdrv                some peripheral driver source code\n\u251c\u2500\u2500 opensbi              opensbi library\n\u251c\u2500\u2500 out                  image generated by Milk-V\n\u251c\u2500\u2500 tdl_sdk              sophgo turnkey deep learning sdk\n\u2514\u2500\u2500 u-boot-2021.10       u-boot source code\n"})}),"\n",(0,n.jsx)(o.h1,{id:"build-image",children:"Build image"}),"\n",(0,n.jsxs)(o.p,{children:["Prepare the Compilation Environment. Using a local Ubuntu system, the officially supported compilation environment is ",(0,n.jsx)(o.code,{children:"Ubuntu Jammy 22.04.x amd64"})," only!"]}),"\n",(0,n.jsx)(o.p,{children:"If you are using other Linux distributions, we strongly recommend that you use the Docker environment to compile to reduce the probability of compilation errors."}),"\n",(0,n.jsx)(o.p,{children:"The following describes the compilation methods in the two environments."}),"\n",(0,n.jsx)(o.p,{children:"In addition, the compilation methods of the V1 and V2 SDKs are basically the same. The following takes the V2 SDK as an example to introduce the SDK compilation steps."}),"\n",(0,n.jsx)(o.h2,{id:"1-compiled-using-ubuntu-2204",children:"1. Compiled using Ubuntu 22.04"}),"\n",(0,n.jsx)(o.h3,{id:"packages-to-be-installed",children:"Packages to be installed"}),"\n",(0,n.jsx)(o.p,{children:"Install the packages that compile dependencies:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"sudo apt install -y pkg-config build-essential ninja-build automake autoconf libtool wget curl git gcc libssl-dev bc slib squashfs-tools android-sdk-libsparse-utils jq python3-distutils scons parallel tree python3-dev python3-pip device-tree-compiler ssh cpio fakeroot libncurses5 flex bison libncurses5-dev genext2fs rsync unzip dosfstools mtools tcl openssh-client cmake expect python-is-python3\n"})}),"\n",(0,n.jsxs)(o.p,{children:["For ",(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk-v2",children:"duo-buildroot-sdk-v2"}),", you also need to install the following tool packages:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"sudo pip install jinja2\n"})}),"\n",(0,n.jsx)(o.h3,{id:"get-sdk-source-code",children:"Get SDK Source Code"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"git clone https://github.com/milkv-duo/duo-buildroot-sdk-v2.git --depth=1\n"})}),"\n",(0,n.jsxs)(o.p,{children:["During the compilation process, Buildroot will automatically download some source packages. SDK V1 has integrated some common source packages and can be compiled directly. In SDK V2, to avoid download failures due to network reasons, you can download the ",(0,n.jsx)(o.code,{children:"dl.tar"})," package in advance and extract it to the ",(0,n.jsx)(o.code,{children:"buildroot"})," directory:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"wget https://github.com/milkv-duo/duo-buildroot-sdk-v2/releases/download/dl/dl.tar\ntar xvf ./dl.tar -C ./duo-buildroot-sdk-v2/buildroot/\n"})}),"\n",(0,n.jsxs)(o.p,{children:["After extraction, the ",(0,n.jsx)(o.code,{children:"dl"})," directory structure in ",(0,n.jsx)(o.code,{children:"buildroot"})," of ",(0,n.jsx)(o.code,{children:"duo-buildroot-sdk-v2"})," is as follows:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-text",children:"\u2514\u2500\u2500 buildroot\n    \u2514\u2500\u2500 dl\n        \u251c\u2500\u2500 acl\n        \u251c\u2500\u2500 alsa-lib\n        \u251c\u2500\u2500 alsa-utils\n        \u251c\u2500\u2500 attr\n        \u251c\u2500\u2500 ...\n"})}),"\n",(0,n.jsx)(o.h3,{id:"1-one-click-compilation",children:"1). One-click Compilation"}),"\n",(0,n.jsxs)(o.p,{children:["Execute one-click compilation script ",(0,n.jsx)(o.code,{children:"build.sh"}),"\uff1a"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"cd duo-buildroot-sdk/\n./build.sh\n"})}),"\n",(0,n.jsx)(o.p,{children:"You will see tips on how to use the compiled script:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"$ ./build.sh\nUsage:\n./build.sh              - Show this menu\n./build.sh lunch        - Select a board to build\n./build.sh [board]      - Build [board] directly, supported boards as follows:\nmilkv-duo-musl-riscv64-sd\nmilkv-duo256m-glibc-arm64-sd\nmilkv-duo256m-musl-riscv64-sd\nmilkv-duos-glibc-arm64-emmc\nmilkv-duos-glibc-arm64-sd\nmilkv-duos-musl-riscv64-emmc\nmilkv-duos-musl-riscv64-sd\n"})}),"\n",(0,n.jsx)(o.p,{children:"Listed at the bottom is the list of currently supported target versions."}),"\n",(0,n.jsx)(o.p,{children:"As shown in the prompt, there are two ways to compile the target version."}),"\n",(0,n.jsxs)(o.p,{children:["The first method is to execute ",(0,n.jsx)(o.code,{children:"./build.sh lunch"})," to bring up the interactive menu, select the version number to be compiled, and press Enter:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"$ ./build.sh lunch\nSelect a target to build:\n1. milkv-duo-musl-riscv64-sd\n2. milkv-duo256m-glibc-arm64-sd\n3. milkv-duo256m-musl-riscv64-sd\n4. milkv-duos-glibc-arm64-emmc\n5. milkv-duos-glibc-arm64-sd\n6. milkv-duos-musl-riscv64-emmc\n7. milkv-duos-musl-riscv64-sd\nWhich would you like:\n"})}),"\n",(0,n.jsx)(o.admonition,{type:"tip",children:(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsx)(o.li,{children:"Duo (64M-DDR) only has RISC-V core, and the default is the SD card image compiled based on musl libc."}),"\n",(0,n.jsx)(o.li,{children:"Duo256M supports RISC-V and ARM cores (choose one of the two). The RISC-V core firmware is compiled based on musl libc, and the ARM core firmware is compiled based on glibc. Only the SD card image is configured."}
1),"\n",(0,n.jsx)(o.li,{children:"DuoS supports RISC-V and ARM cores (choose one of the two). The RISC-V core firmware is compiled based on musl libc, and the ARM core firmware is compiled based on glibc. SD card and eMMC images are configured."}),"\n"]})}),"\n",(0,n.jsxs)(o.p,{children:["The second method is to put the name of the target version after the script and compile it directly. For example, if you need to compile the image of ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd"}),", the command is as follows:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"$ ./build.sh milkv-duos-musl-riscv64-sd\n"})}),"\n",(0,n.jsxs)(o.p,{children:["After successful compilation, you can see the generated image in the ",(0,n.jsx)(o.code,{children:"out"})," directory. The image with the ",(0,n.jsx)(o.code,{children:"*.img"})," suffix is \u200b\u200bthe image burned to the SD card, and the image with the ",(0,n.jsx)(o.code,{children:"*.zip"})," suffix is \u200b\u200bthe image burned to the eMMC."]}),"\n",(0,n.jsxs)(o.p,{children:[(0,n.jsxs)(o.em,{children:["Note: The first compilation will automatically download the required toolchain, which is approximately 840MB in size. Once downloaded, it will be automatically extracted to the ",(0,n.jsx)(o.code,{children:"host-tools"})," directory in the SDK directory. For subsequent compilations, if the ",(0,n.jsx)(o.code,{children:"host-tools"})," directory is detected, the download will not be performed again"]}),"."]}),"\n",(0,n.jsx)(o.h3,{id:"2-step-by-step-compilation",children:"2). Step-by-step Compilation"}),"\n",(0,n.jsxs)(o.p,{children:["If you have not executed the one-click compilation script, you need to manually download the tool chain ",(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/host-tools.git",children:"host-tools"})," and then copy or move it to the SDK root directory:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"git clone https://github.com/milkv-duo/host-tools.git\ncp -a host-tools duo-buildroot-sdk-v2/\n"})}),"\n",(0,n.jsx)(o.p,{children:"Source environment:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"source build/envsetup_milkv.sh\n"})}),"\n",(0,n.jsx)(o.p,{children:"If it is the first time to compile, you will be prompted to select the target to compile:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"Select a target to build:\n1. milkv-duo-musl-riscv64-sd\n2. milkv-duo256m-glibc-arm64-sd\n3. milkv-duo256m-musl-riscv64-sd\n4. milkv-duos-glibc-arm64-emmc\n5. milkv-duos-glibc-arm64-sd\n6. milkv-duos-musl-riscv64-emmc\n7. milkv-duos-musl-riscv64-sd\nWhich would you like:\n"})}),"\n",(0,n.jsx)(o.p,{children:"After selecting the corresponding number, press Enter. After the environment variable is successfully loaded, some information about the current target will be displayed, such as:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"Target Board: milkv-duos-musl-riscv64-sd\nTarget Board Storage: sd\nTarget Board Config: /build/duo-buildroot-sdk-v2/device/target/boardconfig.sh\nTarget Image Config: /build/duo-buildroot-sdk-v2/device/target/genimage.cfg\nBuild tdl-sdk: 1\nOutput dir: /build/duo-buildroot-sdk-v2/install/soc_sg2000_milkv_duos_musl_riscv64_sd\n"})}),"\n",(0,n.jsxs)(o.p,{children:["After the environment is loaded, a link named ",(0,n.jsx)(o.code,{children:"target"})," will be created in the ",(0,n.jsx)(o.code,{children:"device"})," directory, linking to the compilation target directory. The next time you source the environment, when the ",(0,n.jsx)(o.code,{children:"target"})," link is detected, you will no longer be prompted to select a target. If you need to change the compilation target, you can add the ",(0,n.jsx)(o.code,{children:"lunch"})," parameter to re-call the interactive menu for selection:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"source build/envsetup_milkv.sh lunch\n"})}),"\n",(0,n.jsx)(o.p,{children:"After the environment is loaded successfully, enter the following commands in sequence to complete the step-by-step compilation:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"clean_all\nbuild_all\n"})}),"\n",(0,n.jsxs)(o.p,{children:["If you are compiling an SD card image, you also need to execute the following command to generate the ",(0,n.jsx)(o.code,{children:"*.img"})," image:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"pack_sd_image\n"})}),"\n",(0,n.jsxs)(o.p,{children:["For example, if you need to compile the image of ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd"}),", the step-by-step compilation commands are as follows:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"source build/envsetup_milkv.sh milkv-duos-musl-riscv64-sd\n\nclean_all\nbuild_all\npack_sd_image\n"})}),"\n",(0,n.jsx)(o.p,{children:"Generated firmware location:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-text",children:"install/soc_sg2000_milkv_duos_musl_riscv64_sd/milkv-duos-musl-riscv64-sd.img\n"})}),"\n",(0,n.jsxs)(o.p,{children:["Note that the SD card image is ",(0,n.jsx)(o.code,{children:"*.img"})," and the eMMC image is ",(0,n.jsx)(o.code,{children:"upgrade.zip"}),"."]}),"\n",(0,n.jsxs)(o.admonition,{type:"tip",children:[(0,n.jsxs)(o.p,{children:["In addition to using ",(0,n.jsx)(o.code,{children:"build_all"})," for a complete compilation, you can also compile a module separately. Generally speaking, you should first execute ",(0,n.jsx)(o.code,{children:"clean_xxx"})," to clean the intermediate files, and then execute ",(0,n.jsx)(o.code,{children:"build_xxx"})," to recompile. For supported modules, you can enter ",(0,n.jsx)(o.code,{children:"clean_"})," or ",(0,n.jsx)(o.code,{children:"build_"})," and then double-click the ",(0,n.jsx)(o.code,{children:"tab"}
1)," key to view them. The following lists some common module compilation methods:"]}),(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["fsbl: ",(0,n.jsx)(o.code,{children:"clean_fsbl"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_fsbl"})]}),"\n",(0,n.jsxs)(o.li,{children:["uboot: ",(0,n.jsx)(o.code,{children:"clean_uboot"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_uboot"})]}),"\n",(0,n.jsxs)(o.li,{children:["kernel: ",(0,n.jsx)(o.code,{children:"clean_kernel"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_kernel"})]}),"\n",(0,n.jsxs)(o.li,{children:["osdrv: ",(0,n.jsx)(o.code,{children:"clean_osdrv"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_osdrv"})]}),"\n",(0,n.jsxs)(o.li,{children:["cvi_mpi: ",(0,n.jsx)(o.code,{children:"clean_middleware"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_middleware"})]}),"\n",(0,n.jsxs)(o.li,{children:["tdl-sdk: ",(0,n.jsx)(o.code,{children:"clean_tdl_sdk"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_tdl_sdk"})]}),"\n"]})]}),"\n",(0,n.jsx)(o.h2,{id:"2-compiled-using-docker",children:"2. Compiled using Docker"}),"\n",(0,n.jsxs)(o.p,{children:["Docker support is required on hosts running Linux systems. For how to use Docker, please refer to the ",(0,n.jsx)(o.a,{href:"https://docs.docker.com/",children:"official documentation"})," or other tutorials."]}),"\n",(0,n.jsx)(o.p,{children:"We put the SDK source code on the Linux host system and call the Docker image environment provided by Milk-V to compile it."}),"\n",(0,n.jsx)(o.h3,{id:"pull-sdk-code-on-linux-host",children:"Pull SDK code on Linux host"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"git clone https://github.com/milkv-duo/duo-buildroot-sdk-v2.git --depth=1\n"})}),"\n",(0,n.jsxs)(o.p,{children:["During the compilation process, Buildroot will automatically download some source packages. SDK V1 has integrated some common source packages and can be compiled directly. In SDK V2, to avoid download failures due to network reasons, you can download the ",(0,n.jsx)(o.code,{children:"dl.tar"})," package in advance and extract it to the ",(0,n.jsx)(o.code,{children:"buildroot"})," directory:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"wget https://github.com/milkv-duo/duo-buildroot-sdk-v2/releases/download/dl/dl.tar\ntar xvf ./dl.tar -C ./duo-buildroot-sdk-v2/buildroot/\n"})}),"\n",(0,n.jsxs)(o.p,{children:["After extraction, the ",(0,n.jsx)(o.code,{children:"dl"})," directory structure in ",(0,n.jsx)(o.code,{children:"buildroot"})," of ",(0,n.jsx)(o.code,{children:"duo-buildroot-sdk-v2"})," is as follows:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-text",children:"\u2514\u2500\u2500 buildroot\n    \u2514\u2500\u2500 dl\n        \u251c\u2500\u2500 acl\n        \u251c\u2500\u2500 alsa-lib\n        \u251c\u2500\u2500 alsa-utils\n        \u251c\u2500\u2500 attr\n        \u251c\u2500\u2500 ...\n"})}),"\n",(0,n.jsx)(o.h3,{id:"enter-the-sdk-code-directory",children:"Enter the SDK code directory"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"cd duo-buildroot-sdk-v2\n"})}),"\n",(0,n.jsx)(o.h3,{id:"pull-the-docker-image-and-run",children:"Pull the Docker image and run"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:'docker run --privileged -itd --name duodocker -v "$(pwd)":/home/work milkvtech/milkv-duo:latest /bin/bash\n'})}),"\n",(0,n.jsx)(o.p,{children:"Description of some parameters in the command:"}),"\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"--privileged"})," starts the container in privileged mode."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"duodocker"})," Docker name, you can use the name you want to use."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"$(pwd)"})," The current directory, here is the duo-buildroot-sdk directory that was 'cd' to in the previous step."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"-v $(pwd):/home/work"}),"  Bind the current code directory to the /home/work directory in the Docker image."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"milkvtech/milkv-duo:latest"})," The Docker image provided by Milk-V will be automatically downloaded from hub.docker.com for the first time."]}),"\n"]}),"\n",(0,n.jsxs)(o.p,{children:["After Docker runs successfully, you can use the ",(0,n.jsx)(o.code,{children:"docker ps -a"})," command to view the running status:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:'$ docker ps -a\nCONTAINER ID   IMAGE                        COMMAND       CREATED       STATUS       PORTS     NAMES\n8edea33c2239   milkvtech/milkv-duo:latest   "/bin/bash"   2 hours ago   Up 2 hours             duodocker\n'})}),"\n",(0,n.jsx)(o.admonition,{type:"tip",children:(0,n.jsxs)(o.p,{children:["If the image on the Docker server is updated, you can use the ",(0,n.jsx)(o.code,{children:"docker pull milkvtech/milkv-duo:latest"})," command to synchronize the latest image."]})}),"\n",(0,n.jsx)(o.h3,{id:"1-one-click-compilation-using-docker",children:"1). One-click compilation using Docker"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:'docker exec -it duodocker /bin/bash -c "cd /home/work && c
1at /etc/issue && export FORCE_UNSAFE_CONFIGURE=1 && ./build.sh [board]"\n'})}),"\n",(0,n.jsxs)(o.p,{children:["Note that the ",(0,n.jsx)(o.code,{children:"./build.sh [board]"})," at the end of the command is the same as the previous usage in the one-click compilation instructions in Ubuntu 22.04. Use ",(0,n.jsx)(o.code,{children:"./build.sh"})," can see how to use the command, use ",(0,n.jsx)(o.code,{children:"./ build.sh lunch"})," can bring up the interactive selection menu, use ",(0,n.jsx)(o.code,{children:"./build.sh [board]"})," to directly compile the target version, ",(0,n.jsx)(o.code,{children:"[board]"})," can be replaced with:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{children:"milkv-duo-musl-riscv64-sd\nmilkv-duo256m-glibc-arm64-sd\nmilkv-duo256m-musl-riscv64-sd\nmilkv-duos-glibc-arm64-emmc\nmilkv-duos-glibc-arm64-sd\nmilkv-duos-musl-riscv64-emmc\nmilkv-duos-musl-riscv64-sd\n"})}),"\n",(0,n.jsx)(o.p,{children:"Description of some parameters in the command:"}),"\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"duodocker"})," The name of the running Docker must be consistent with the name set in the previous step."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:'"*"'})," In quotes is the shell command to be run in the Docker image."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"cd /home/work"})," Switch to the /home/work directory. Since this directory has been bound to the host's code directory during runtime, the /home/work directory in Docker is the source code directory of the SDK."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"cat /etc/issue"})," Displays the version number of the image used by Docker. It is currently Ubuntu 22.04.3 LTS and is used for debugging."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"export FORCE_UNSAFE_CONFIGURE=1"})," By default, Docker uses the root user to compile. You need to use this environment variable."]}),"\n",(0,n.jsxs)(o.li,{children:[(0,n.jsx)(o.code,{children:"./build.sh [board]"})," Execute one-click compilation script."]}),"\n"]}),"\n",(0,n.jsxs)(o.p,{children:["For example, if you need to compile the image of ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd"}),", the command is as follows:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:'docker exec -it duodocker /bin/bash -c "cd /home/work && cat /etc/issue && export FORCE_UNSAFE_CONFIGURE=1 && ./build.sh milkv-duos-musl-riscv64-sd"\n'})}),"\n",(0,n.jsxs)(o.p,{children:["After successful compilation, you can see the generated SD card burning image ",(0,n.jsx)(o.code,{children:"*.img"})," in the ",(0,n.jsx)(o.code,{children:"out"})," directory."]}),"\n",(0,n.jsx)(o.h3,{id:"2-compile-step-by-step-using-docker",children:"2). Compile step by step using Docker"}),"\n",(0,n.jsxs)(o.p,{children:["If you have not executed the one-click compilation script, you need to manually download the tool chain ",(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/host-tools.git",children:"host-tools"})," and then copy or move it to the SDK root directory:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"git clone https://github.com/milkv-duo/host-tools.git\ncp -a host-tools duo-buildroot-sdk-v2/\n"})}),"\n",(0,n.jsxs)(o.p,{children:["Step-by-step compilation requires logging into Docker to operate. Use the command ",(0,n.jsx)(o.code,{children:"docker ps -a"})," to view and record the ID number of the container, such as ",(0,n.jsx)(o.code,{children:"8edea33c2239"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["If ",(0,n.jsx)(o.code,{children:"duodocker"})," is not in the list, the container may have been stopped. You need to rerun it and then check the ID number in the window:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"cd duo-buildroot-sdk-v2/\ndocker run --privileged -itd --name duodocker -v $(pwd):/home/work milkvtech/milkv-duo:latest /bin/bash\ndocker ps -a\n"})}),"\n",(0,n.jsx)(o.p,{children:"Enter Docker:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"docker exec -it 8edea33c2239 /bin/bash\n"})}),"\n",(0,n.jsx)(o.p,{children:"Enter the code directory bound in Docker\uff1a"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"root@8edea33c2239:/# cd /home/work/\n"})}),"\n",(0,n.jsx)(o.p,{children:"Set environment variables. By default, Docker is compiled as the root user. You need to configure the environment variables:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"export FORCE_UNSAFE_CONFIGURE=1\n"})}),"\n",(0,n.jsx)(o.p,{children:"Source environment:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"source build/envsetup_milkv.sh\n"})}),"\n",(0,n.jsx)(o.p,{children:"If it is the first time to compile, you will be prompted to select the target to compile:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"Select a target to build:\n1. milkv-duo-musl-riscv64-sd\n2. milkv-duo256m-glibc-arm64-sd\n3. milkv-duo256m-musl-riscv64-sd\n4. milkv-duos-glibc-arm64-emmc\n5. milkv-duos-glibc-arm64-sd\n6. milkv-duos-musl-riscv64-emmc\n7. milkv-duos-musl-riscv64-sd\nWhich would you like:\n"})}),"\n",(0,n.jsx)(o.p,{children:"After selecting the corresponding number, press Enter. After the environment variable is successfully loaded, some information about the current target will be displayed, such as:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"Target Board: milkv-duos-musl-riscv64-sd\nTarget Board Storage: sd\nTarget Board Config: /build/duo-buildroot-sdk-v2/device/target/boardconfig.sh\nTarget Image Config: /build/duo-buildroot-sdk-v2/device/target/genimage.cfg\nBuild tdl-sdk: 1\nOutput dir: /build/duo-buildroot-sdk-v2/install/soc_sg2000_milkv_duos_musl_riscv64_sd\n"})}),"\n",(0,n.jsxs)(o.p,{children:["After the environment is loaded, a link named ",(0,n.jsx)(o.code,{children:"target"})," will be created in the ",(0,n.jsx)(o.code,{children:"device"})," directory, linking to the compilation target directory. The next time you source the environment, when the ",(0,n.jsx)(o.code,{children:"target"})," link is detected, you will no longer be prompted to select a target. If you need to change the compilation target, you can add the ",(0,n.jsx)(o.code,{children:"lunch"})," parameter to re-call the interactive menu for selection:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"source build/envsetup_milkv.sh lunch\n"})}),"\n",(0,n.jsx)(o.p,{children:"After the environment is loaded successfully, enter the following commands in sequence to complete the step-by-step compilation:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"clean_all\nbuild_all\n"})}),"\n",(0,n.jsxs)(o.p,{children:["If you are compiling an SD card image, you also need to execute the following command to generate the ",(0,n.jsx)(o.code,{children:"*.img"})," image:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"pack_sd_image\n"})}),"\n",(0,n.jsxs)(o.p,{children:["For example, if you need to compile the image of ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd"}),", the step-by-step compilation commands are as follows:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"source build/envsetup_milkv.sh milkv-duos-musl-riscv64-sd\n\nclean_all\nbuild_all\npack_sd_image\n"})}),"\n",(0,n.jsx)(o.p,{children:"Generated firmware location:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-text",children:"install/soc_sg2000_milkv_duos_musl_riscv64_sd/milkv-duos-musl-riscv64-sd.img\n"})}),"\n",(0,n.jsxs)(o.p,{children:["Note that the SD card image is ",(0,n.jsx)(o.code,{children:"*.img"})," and the eMMC image is ",(0,n.jsx)(o.code,{children:"upgrade.zip"}),"."]}),"\n",(0,n.jsxs)(o.admonition,{type:"tip",children:[(0,n.jsxs)(o.p,{children:["In addition to using ",(0,n.jsx)(o.code,{children:"build_all"})," for a complete compilation, you can also compile a module separately. Generally speaking, you should first execute ",(0,n.jsx)(o.code,{children:"clean_xxx"})," to clean the intermediate files, and then execute ",(0,n.jsx)(o.code,{children:"build_xxx"})," to recompile. For supported modules, you can enter ",(0,n.jsx)(o.code,{children:"clean_"})," or ",(0,n.jsx)(o.code,{children:"build_"})," and then double-click the ",(0,n.jsx)(o.code,{children:"tab"}
1)," key to view them. The following lists some common module compilation methods:"]}),(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["fsbl: ",(0,n.jsx)(o.code,{children:"clean_fsbl"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_fsbl"})]}),"\n",(0,n.jsxs)(o.li,{children:["uboot: ",(0,n.jsx)(o.code,{children:"clean_uboot"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_uboot"})]}),"\n",(0,n.jsxs)(o.li,{children:["kernel: ",(0,n.jsx)(o.code,{children:"clean_kernel"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_kernel"})]}),"\n",(0,n.jsxs)(o.li,{children:["osdrv: ",(0,n.jsx)(o.code,{children:"clean_osdrv"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_osdrv"})]}),"\n",(0,n.jsxs)(o.li,{children:["cvi_mpi: ",(0,n.jsx)(o.code,{children:"clean_middleware"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_middleware"})]}),"\n",(0,n.jsxs)(o.li,{children:["tdl-sdk: ",(0,n.jsx)(o.code,{children:"clean_tdl_sdk"}),"\uff0c",(0,n.jsx)(o.code,{children:"build_tdl_sdk"})]}),"\n"]})]}),"\n",(0,n.jsxs)(o.p,{children:["After compilation is completed, you can use the ",(0,n.jsx)(o.code,{children:"exit"})," command to exit the Docker environment:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"root@8edea33c2239:/home/work# exit\n"})}),"\n",(0,n.jsx)(o.p,{children:"The generated firmware can also be seen in the host code directory."}),"\n",(0,n.jsx)(o.h3,{id:"stop-docker",children:"Stop Docker"}),"\n",(0,n.jsx)(o.p,{children:"After compilation is completed, if the above Docker running environment is no longer needed, you can stop it first and then delete it:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"docker stop 8edea33c2239\ndocker rm 8edea33c2239\n"})}),"\n",(0,n.jsx)(o.h2,{id:"3-other-compilation-considerations",children:"3. Other compilation considerations"}),"\n",(0,n.jsx)(o.p,{children:"If you want to try to compile this SDK in an environment other than the above two environments, the following are things you may 
1need to pay attention to, for reference only."}),"\n",(0,n.jsx)(o.h3,{id:"cmake-version",children:"cmake version"}),"\n",(0,n.jsxs)(o.p,{children:["Note\uff1a",(0,n.jsx)(o.code,{children:"cmake"})," minimum version requirement is ",(0,n.jsx)(o.code,{children:"3.16.5"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["Check the version of ",(0,n.jsx)(o.code,{children:"cmake"})," in the system:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"cmake --version\n"})}),"\n",(0,n.jsxs)(o.p,{children:["For example, the version of ",(0,n.jsx)(o.code,{children:"cmake"})," installed using apt in the ",(0,n.jsx)(o.code,{children:"Ubuntu 20.04"})," is:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{children:"cmake version 3.16.3\n"})}),"\n",(0,n.jsxs)(o.p,{children:["The minimum requirement of this SDK is not met. Manual installation of the latest version ",(0,n.jsx)(o.code,{children:"3.27.6"})," is needed:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"wget https://github.com/Kitware/CMake/releases/download/v3.27.6/cmake-3.27.6-linux-x86_64.sh\nchmod +x cmake-3.27.6-linux-x86_64.sh\nsudo sh cmake-3.27.6-linux-x86_64.sh --skip-license --prefix=/usr/local/\n"})}),"\n",(0,n.jsxs)(o.p,{children:["When manually installed, ",(0,n.jsx)(o.code,{children:"cmake"})," is located in ",(0,n.jsx)(o.code,{children:"/usr/local/bin"}),". To check its version, use the command ",(0,n.jsx)(o.code,{children:"cmake --version"}),", which should display:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{children:"cmake version 3.27.6\n"})}),"\n",(0,n.jsx)(o.h3,{id:"compiling-with-windows-linux-subsystem-wsl",children:"Compiling with Windows Linux Subsystem (WSL)"}),"\n",(0,n.jsx)(o.p,{children:"If you wish to perform the compilation with WSL, there's an small issue building the image.\nThe $PATH, due Windows interoperability, has Windows environment variables which include some spaces between the paths."}),"\n",(0,n.jsxs)(o.p,{children:["To solve this problem you need to change the ",(0,n.jsx)(o.code,{children:"/etc/wsl.conf"})," file and add the following lines:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{children:"[interop]\nappendWindowsPath = false\n"})}),"\n",(0,n.jsxs)(o.p,{children:["After that, you need to reboot the WSL with ",(0,n.jsx)(o.code,{children:"wsl.exe --reboot"}),". Then you able to run the ",(0,n.jsx)(o.code,{children:"./build.sh"})," script or the ",(0,n.jsx)(o.code,{children:"build_all"})," line in the step-by-step compilation method.\nTo rollback this change in ",(0,n.jsx)(o.code,{children:"/etc/wsl.conf"})," file set ",(0,n.jsx)(o.code,{children:"appendWindowsPath"})," as true. To reboot the WSL, can you use the Windows PowerShell command ",(0,n.jsx)(o.code,{children:"wsl.exe --shutdown"})," then ",(0,n.jsx)(o.code,{children:"wsl.exe"}),", after that the Windows environment variables become avaliable again in $PATH."]}),"\n",(0,n.jsx)(o.h2,{id:"4-add-application-packages",children:"4. Add application packages"}),"\n",(0,n.jsx)(o.p,{children:"Buildroot is a lightweight embedded Linux system building tool. The system it generates does not have the apt package management tool like the Ubuntu system to download and use application packages. Duo's default SDK has added some commonly used tools or commands. If you need to add your own applications, you need to make some modifications to the SDK and recompile to generate the required system firmware."}),"\n",(0,n.jsx)(o.p,{children:"The following introduces several common methods for adding application packages in Buildroot."}),"\n",(0,n.jsx)(o.h3,{id:"enable-commands-in-busybox",children:"Enable commands in Busybox"}),"\n",(0,n.jsx)(o.p,{children:"In a system built using Buildroot, some basic commands are provided by busybox. You can check whether the configuration file of busybox contains the commands you need, enable it and recompile. The location of the configuration file of busybox is:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{children:"buildroot/package/busybox/busybox.config\n"})}),"\n",(0,n.jsx)(o.p,{children:"For example, the timeout command, how to enable it:"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-diff",metastring:"{9,10}",children:"diff --git a/buildroot/package/busybox/busybox.config b/buildroot/package/busybox/busybox.config\nindex d7d58f064..b268cd6f8 100644\n--- a/buildroot/package/busybox/busybox.config\n+++ b/buildroot/package/busybox/busybox.config\n@@ -304,7 +304,7 @@ CONFIG_TEST=y\n CONFIG_TEST1=y\n CONFIG_TEST2=y\n CONFIG_FEATURE_TEST_64=y\n-# CONFIG_TIMEOUT is not set\n+CONFIG_TIMEOUT=y\n CONFIG_TOUCH=y\n # CONFIG_FEATURE_TOUCH_NODEREF is not set\n CONFIG_FEATURE_TOUCH_SUSV3=y\n"})}),"\n",(0,n.jsxs)(o.p,{children:["Refer to this commit: ",(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk/commit/2833c24f11bb48776094265b7b16cfde87f86083",children:"busybox: add timeout command"})]}),"\n",(0,n.jsx)(o.h3,{id:"configure-application-packages-preset-in-buildroot",children:"Configure application packages preset in Buildroot"}),"\n",(0,n.jsxs)(o.p,{children:["In addition, a large number of application packages are preset in Buildroot. The required programs are generated by downloading the source code and compiling them. The preset application packages of Buildroot can be viewed in the ",(0,n.jsx)(o.code,{children:"buildroot/package"})," directory."]}),"\n",(0,n.jsxs)(o.p,{children:["Configuring to enable or disable an application package is implemented in the target board's configuration file. Taking the ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd"})," target as an example, its buildroot configuration file is:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{children:"buildroot/configs/milkv-duos-musl-riscv64-sd_defconfig\n"})}),"\n",(0,n.jsx)(o.p,{children:"We can compile the SDK as a whole on the host (such as Ubuntu), and then go to the Buildroot compilation directory to configure the relevant application packages through command line menu interaction."}),"\n",(0,n.jsxs)(o.ol,{children:["\n",(0,n.jsxs)(o.li,{children:["\n",(0,n.jsx)(o.p,{children:"Enter the Buildroot compilation directory"}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"cd buildroot/output/milkv-duos-musl-riscv64-sd/\n"})}),"\n",(0,n.jsxs)(o.p,{children:["You can use the ",(0,n.jsx)(o.code,{children:"make show-targets"})," command to view the currently used application packages:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"$ make show-targets\nbusybox coreutils dhcpcd dnsmasq dropbear duo-pinmux e2fsprogs evtest expat fio freetype gdb host-acl host-attr host-autoconf host-automake host-e2fsprogs host-fakeroot host-genimage host-libtool host-libzlib host-m4 host-makedevs host-mkpasswd host-patchelf host-pkgconf host-skeleton host-util-linux host-xz host-zlib htop ifupdown-scripts initscripts iperf3 json-c kmod libevent libffi libnl libopenssl libxml2 libxslt libzlib musl-compat-headers ncurses ntp openssl python-cffi python-evdev python-freetype python-lxml python-modbus-tk python-pillow python-pinpong python-pip python-psutil python-pycparser python-serial python-setuptools python-smbus-cffi python-spidev python3 skeleton 
1skeleton-init-common skeleton-init-sysv spidev_test strace stress-ng tar toolchain toolchain-external toolchain-external-custom urandom-scripts util-linux wpa_supplicant zlib rootfs-ext2 rootfs-tar\n"})}),"\n"]}),"\n",(0,n.jsxs)(o.li,{children:["\n",(0,n.jsx)(o.p,{children:"Configure Buildroot"}),"\n",(0,n.jsxs)(o.p,{children:["Execute the ",(0,n.jsx)(o.code,{children:"make menuconfig"})," command to bring up the interactive menu:"]}),"\n",(0,n.jsx)(i,{src:"/docs/duo/buildroot/milkv-duo-buildroot-sdk-01.webp",maxWidth:"100%",align:"left"}),"\n",(0,n.jsxs)(o.p,{children:["Find the required application package according to the classification in ",(0,n.jsx)(o.code,{children:"Target packages"}),". If you don't know the specific location of the application package, you can press the ",(0,n.jsx)(o.code,{children:"/"})," key to search for the package name. For example, if you want to install the ",(0,n.jsx)(o.code,{children:"tar"})," command, since searching for ",(0,n.jsx)(o.code,{children:"tar"})," will bring up too many other irrelevant content, you can search for ",(0,n.jsx)(o.code,{children:"package_tar"}),". And see that ",(0,n.jsx)(o.code,{children:"=n"})," is currently disabled. Its location is in the ",(0,n.jsx)(o.code,{children:"System tools"})," category of ",(0,n.jsx)(o.code,{children:"Target packages"}),". You can double-click the ",(0,n.jsx)(o.code,{children:"ESC"})," key to return to the main page. Then enter the corresponding position on the interface, or you can directly enter the position according to the number prompted earlier:"]}),"\n",(0,n.jsx)(i,{src:"/docs/duo/buildroot/milkv-duo-buildroot-sdk-02.webp",maxWidth:"100%",align:"left"}),"\n",(0,n.jsx)(o.p,{children:"Press the space bar to enable:"}),"\n",(0,n.jsx)(i,{src:"/docs/duo/buildroot/milkv-duo-buildroot-sdk-03.webp",maxWidth:"100%",align:"left"}),"\n",(0,n.jsxs)(o.p,{children:["Double-click the ",(0,n.jsx)(o.code,{children:"ESC"})," key continuously to exit the main interface. When prompted whether to save, the default is YES. Just press Enter to save and exit:"]}),"\n",(0,n.jsx)(i,{src:"/docs/duo/buildroot/milkv-duo-buildroot-sdk-04.webp",maxWidth:"100%",align:"left"}),"\n",(0,n.jsxs)(o.p,{children:["Execute the ",(0,n.jsx)(o.code,{children:"make savedefconfig"})," command to save the modified configuration to the original configuration file. Use the ",(0,n.jsx)(o.code,{children:"git status"})," command to confirm. You can see that the original configuration file has been modified:"]}),"\n",(0,n.jsx)(i,{src:"/docs/duo/buildroot/milkv-duo-buildroot-sdk-05.webp",maxWidth:"100%",align:"left"}),"\n",(0,n.jsx)(o.p,{children:"At this point, go back to the SDK root directory and recompile."}),"\n",(0,n.jsxs)(o.admonition,{type:"tip",children:[(0,n.jsxs)(o.p,{children:["Here you can also compare the differences between the old configuration file and the new configuration file in the compilation directory, and manually modify the parts that need to be changed directly into the original configuration file ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd_defconfig"}),":"]}),(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-diff",children:"diff -u .config.old .config\n"})})]}),"\n",(0,n.jsxs)(o.p,{children:["After starting with the newly compiled image, test the newly added command on the Duo device. If a ",(0,n.jsx)(o.code,{children:"not found"})," error occurs, it may be that the ",(0,n.jsx)(o.code,{children:".mk"})," configuration file of the package needs to be supplemented with gcc parameters, mainly ",(0,n.jsx)(o.code,{children:"TARGET_CFLAGS"})," and The two parameters of ",(0,n.jsx)(o.code,{children:"TARGET_LDFLAGS"})," need to be added. You can refer to the following commits:"]}),"\n",(0,n.jsxs)(o.ol,{children:["\n",(0,n.jsx)(o.li,{children:(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk/commit/6ebbd6e219d3efcd9b95086c75702f4f717e7f03#diff-1a84d28825d604f941100ff9b50ec8d63bf84535a3dd6f7e62c421a657e6556a",children:"buildroot: enable fio"})}),"\n",(0,n.jsx)(o.li,{children:(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk/commit/84d6b72eb6c9ff467410376fc982b5ee4f8e3d1f#diff-d0fb4ce2e7555c5cc5399aeaa75e4bf5fd429f034f4d00457f450a994204b97f",children:"buildroot: enable spidev_test"})}),"\n",(0,n.jsx)(o.li,{children:(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk/commit/cdd4fabb6100f87a61ca7560def558cd9e38f91a",children:"buildroot: fix build parameter for coremark package"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(o.h3,{id:"add-your-own-application-package",children:"Add your own application package"}),"\n",(0,n.jsxs)(o.p,{children:["Compile and test your own application. The method of integrating it into the Buildroot project is not recommended. It is recommended to use method ",(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-examples",children:"duo-examples"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"If you really need to compile your application in Buildroot package mode, you can refer to the configuration of the preset package in Buildroot to add it. Here are a few reference links:"}),"\n",(0,n.jsxs)(o.ol,{children:["\n",(0,n.jsx)(o.li,{children:(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk/commit/11caee79c7a48f7f6fd4a5d352ccf8976857d522",children:"buildroot: add python-evdev required by the pinpong library"})}),"\n",(0,n.jsx)(o.li,{children:(0,n.jsx)(o.a,{href:"https://github.com/milkv-duo/duo-buildroot-sdk/commit/165fc3c4c1adca1d1f635fd2069a5ad67d895c7c",children:"buildroot: add python-freetype required by the pinpong library"})}),"\n"]}),"\n",(0,n.jsxs)(o.p,{children:["Mainly refer to the content added in ",(0,n.jsx)(o.code,{children:"buildroot-2021.05/package"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"5-delete-application-packages",children:"5. Delete application packages"}),"\n",(0,n.jsxs)(o.p,{children:["If you need to delete some unnecessary application packages to speed up compilation, or disable some unnecessary packages when compiling the firmware by yourself, you can use the ",(0,n.jsx)(o.code,{children:"make menuconfig"})," method of opening the Buildroot application package mentioned above to disable related packages."]}),"\n",(0,n.jsxs)(o.p,{children:["You can also delete the corresponding package name in the Buildroot configuration file. Take the ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd"})," target as an example. For example, if you do not need to compile Python-related libraries, you can make the following modifications and recompile to generate firmware."]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-diff",metastring:'title="buildroot/configs/milkv-duos-musl-riscv64-sd_defconfig"',children:"diff --git a/buildroot/configs/milkv-duos-musl-riscv64-sd_defconfig b/buildroot/configs/milkv-duos-musl-riscv64-sd_defconfig\nindex 2bc8cd5e3..e78901afb 100644\n--- a/buildroot/configs/milkv-duos-musl-riscv64-sd_defconfig\n+++ b/buildroot/configs/milkv-duos-musl-riscv64-sd_defconfig\n@@ -330,25 +330,6 @@ BR2_PACKAG
1E_EVTEST=y\n # BR2_PACKAGE_FCONFIG is not set\n BR2_PACKAGE_FLASHROM_ARCH_SUPPORTS=y\n \n-BR2_PACKAGE_PYTHON3=y\n-BR2_PACKAGE_PYTHON3_PY_PYC=y\n-BR2_PACKAGE_PYTHON_LXML=y\n-BR2_PACKAGE_PYTHON_PIP=y\n-BR2_PACKAGE_PYTHON_SETUPTOOLS=y\n-BR2_PACKAGE_PYTHON3_SSL=y\n-\n-BR2_PACKAGE_PYTHON_SERIAL=y\n-BR2_PACKAGE_PYTHON_PILLOW=y\n-BR2_PACKAGE_PYTHON_SMBUS_CFFI=y\n-BR2_PACKAGE_PYTHON_SPIDEV=y\n-BR2_PACKAGE_PYTHON_MODBUS_TK=y\n-BR2_PACKAGE_PYTHON_EVDEV=y\n-BR2_PACKAGE_PYTHON_FREETYPE=y\n-\n-BR2_PACKAGE_PYTHON_PINPONG=y\n-\n-BR2_PACKAGE_PYTHON_PSUTIL=y\n-\n #\n # Compression and decompression\n #\n"})}),"\n",(0,n.jsx)(o.h2,{id:"6-frequently-asked-questions",children:"6. Frequently Asked Questions"}),"\n",(0,n.jsx)(o.h3,{id:"buildroot-troubleshooting-method",children:"Buildroot troubleshooting method"}),"\n",(0,n.jsx)(o.p,{children:"Buildroot in the SDK enables top-level parallel compilation by default to speed up compilation. However, when a compilation error occurs, it is inconvenient to analyze the error log, so we can delete it in the config file first, and then reopen it after the problem is solved."}),"\n",(0,n.jsxs)(o.p,{children:["Take the ",(0,n.jsx)(o.code,{children:"milkv-duos-musl-riscv64-sd"})," target as an example. After deleting the line in its configuration file, delete the ",(0,n.jsx)(o.code,{children:"buildroot/output"})," directory and recompile:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",metastring:'title="buildroot/configs/milkv-duos-musl-riscv64-sd_defconfig"',children:"BR2_PER_PACKAGE_DIRECTORIES=y\n"})}),"\n",(0,n.jsxs)(o.p,{children:["When a compilation error occurs, in addition to checking the error information of the compilation terminal, you can also check the complete log in ",(0,n.jsx)(o.code,{children:"build/br.log"})," for troubleshooting."]}),"\n",(0,n.jsx)(o.h3,{id:"buildroot-package-download-failed",children:"Buildroot package download failed"}),"\n",(0,n.jsxs)(o.p,{children:["During the compilation process, Buildroot will automatically download some source packages. SDK V1 has integrated some common source packages and can be compiled directly. In SDK V2, to avoid download failures due to network problems, you can download the ",(0,n.jsx)(o.code,{children:"dl.tar"})," package in advance and extract it to the ",(0,n.jsx)(o.code,{children:"buildroot"})," directory before recompiling:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-bash",children:"rm -rf ./buildroot/output ./buildroot/dl\nwget https://github.com/milkv-duo/duo-buildroot-sdk-v2/releases/download/dl/dl.tar\ntar xvf ./dl.tar -C ./buildroot/\n"})}),"\n",(0,n.jsxs)(o.p,{children:["After decompression, the ",(0,n.jsx)(o.code,{children:"dl"})," directory structure in ",(0,n.jsx)(o.code,{children:"buildroot"})," is as follows:"]}),"\n",(0,n.jsx)(o.pre,{children:(0,n.jsx)(o.code,{className:"language-text",children:"\u2514\u2500\u2500 buildroot\n    \u2514\u2500\u2500 dl\n        \u251c\u2500\u2500 acl\n        \u251c\u2500\u2500 alsa-lib\n        \u251c\u2500\u2500 alsa-utils\n        \u251c\u2500\u2500 attr\n        \u251c\u2500\u2500 ...\n"})})]})}function h(e={}){const{wrapper:o}={...(0,s.a)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},11151:(e,o,i)=>{i.d(o,{Z:()=>t,a:()=>l});var n=i(67294);const s={},d=n.createContext(s);function l(e){const o=n.useContext(d);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function t(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),n.createElement(d.Provider,{value:o},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.