----------------------------------------------------------------------------------------------------------------------------
开发板 :NanoPC-T4开发板
eMMC :16GB
LPDDR3:4GB
显示屏 :15.6英寸HDMI接口显示屏
u-boot :2017.09
linux :5.2.8
----------------------------------------------------------------------------------------------------------------------------
在前面的章节,我们已经介绍了在RK3399上面移植uboot,这一节我们将移植linux 5.2.8到RK3399上。
一、linux内核
像uboot一样,linux内核通常有三种:
- linux官方源码:https://github.com/torvalds/linux,linux官方源码是由linux官方维护,支持非常全面的芯片,但对具体某款开发板支持情况一般;
- 半导体厂商瑞芯微官方源码:https://github.com/rockchip-linux/kernel,半导体厂商基于linux官方源码进行修改,对自家的芯片进行完善的支持,针对某款处理器支持情况较好;
- 开发板友善之家官方源码:https://github.com/friendlyarm/kernel-rockchip,开发板厂商基于半导体厂商维护的linux,对自家的开发板进行板级支持,针对某款开发板支持情况较好;
由于Rockchip官方提供的内核版本较低,所以这里我们直接去linux官方去下载,然后后面参考开发板友善之家官方源码修改使其能够支持NanoPC-T4开发板。
1.1 源码下载
内核源码下载地址为:https://www.kernel.org/,这里我们不下载最新的6.3.2版本,我们和之前介绍的Mini2440内核移植一样,选择5.2.8版本:
也可以到内核镜像网址下载https://mirrors.edge.kernel.org/pub/linux/kernel/,这里下载速度更快。
如果下载速度太慢,无法下载,提供另一个链接:http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/。
我们这里下载linux-5.2.8版本,执行如下命令:
root@zhengyang:/work/sambashare/rk3399# wget http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/v5.x/linux-5.2.8.tar.gz
这里我是下载到/work/sambashare/rk3399路径下的,这个路径是用来专门存放与rk3399相关的内容。
解压源码:
root@zhengyang:/work/sambashare/rk3399# tar -xvf linux-5.2.8.tar.gz
关于linux内核的目录结构我们之前已经介绍过,这里就不再重复叙述了。
root@zhengyang:/work/sambashare/rk3399# cd linux-5.2.8/ root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# ll 总用量 840 drwxrwxr-x 24 root root 4096 Aug 9 2019 ./ drwxr-xr-x 8 root root 4096 May 17 04:16 ../ drwxrwxr-x 27 root root 4096 Aug 9 2019 arch/ drwxrwxr-x 3 root root 4096 Aug 9 2019 block/ drwxrwxr-x 2 root root 4096 Aug 9 2019 certs/ -rw-rw-r-- 1 root root 14943 Aug 9 2019 .clang-format -rw-rw-r-- 1 root root 59 Aug 9 2019 .cocciconfig -rw-rw-r-- 1 root root 423 Aug 9 2019 COPYING -rw-rw-r-- 1 root root 99486 Aug 9 2019 CREDITS drwxrwxr-x 4 root root 4096 Aug 9 2019 crypto/ drwxrwxr-x 122 root root 12288 Aug 9 2019 Documentation/ drwxrwxr-x 140 root root 4096 Aug 9 2019 drivers/ drwxrwxr-x 73 root root 4096 Aug 9 2019 fs/ -rw-rw-r-- 1 root root 71 Aug 9 2019 .get_maintainer.ignore -rw-rw-r-- 1 root root 30 Aug 9 2019 .gitattributes -rw-rw-r-- 1 root root 1658 Aug 9 2019 .gitignore drwxrwxr-x 27 root root 4096 Aug 9 2019 include/ drwxrwxr-x 2 root root 4096 Aug 9 2019 init/ drwxrwxr-x 2 root root 4096 Aug 9 2019 ipc/ -rw-rw-r-- 1 root root 1513 Aug 9 2019 Kbuild -rw-rw-r-- 1 root root 563 Aug 9 2019 Kconfig drwxrwxr-x 18 root root 4096 Aug 9 2019 kernel/ drwxrwxr-x 15 root root 12288 Aug 9 2019 lib/ drwxrwxr-x 6 root root 4096 Aug 9 2019 LICENSES/ -rw-rw-r-- 1 root root 12316 Aug 9 2019 .mailmap -rw-rw-r-- 1 root root 512407 Aug 9 2019 MAINTAINERS -rw-rw-r-- 1 root root 60262 Aug 9 2019 Makefile drwxrwxr-x 3 root root 4096 Aug 9 2019 mm/ drwxrwxr-x 70 root root 4096 Aug 9 2019 net/ -rw-rw-r-- 1 root root 727 Aug 9 2019 README drwxrwxr-x 29 root root 4096 Aug 9 2019 samples/ drwxrwxr-x 15 root root 4096 Aug 9 2019 scripts/ drwxrwxr-x 11 root root 4096 Aug 9 2019 security/ drwxrwxr-x 26 root root 4096 Aug 9 2019 sound/ drwxrwxr-x 36 root root 4096 Aug 9 2019 tools/ drwxrwxr-x 2 root root 4096 Aug 9 2019 usr/ drwxrwxr-x 4 root root 4096 Aug 9 2019 virt/
1.2 配置Makefile
修改顶层的 Makefile,打开 Makefile 文件,找到下面语句:
ARCH ?= $(SUBARCH)
修改为:
ARCH ?= arm64
CROSS_COMPILE ?= arm-linux-
其中,ARCH 是指定目标平台为arm64,CROSS_COMPILE是指定交叉编译器,这里指定的是系统默认的交叉编译器,如要使用其它的,则要把编译器的全路径在这里写出。
1.3 内核defconfig配置
接下来要做的就是内核配置、编译了。单板的默认配置文件在arch/arm64/configs目录下:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# ll arch/arm64/configs/defconfig -rw-rw-r-- 1 root root 18417 Aug 9 2019 arch/arm64/configs/defconfig
在这个目录下就这一个配置,我们也没有其它选择了,那只能走一步看一步了。
配置文件defconfig其定义如下:
CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_PREEMPT=y CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_NUMA_BALANCING=y CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_HUGETLB=y CONFIG_CPUSETS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_USER_NS=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y CONFIG_ARCH_AGILEX=y CONFIG_ARCH_SUNXI=y CONFIG_ARCH_ALPINE=y CONFIG_ARCH_BCM2835=y CONFIG_ARCH_BCM_IPROC=y CONFIG_ARCH_BERLIN=y CONFIG_ARCH_BRCMSTB=y CONFIG_ARCH_EXYNOS=y CONFIG_ARCH_K3=y CONFIG_ARCH_LAYERSCAPE=y CONFIG_ARCH_LG1K=y CONFIG_ARCH_HISI=y CONFIG_ARCH_MEDIATEK=y CONFIG_ARCH_MESON=y CONFIG_ARCH_MVEBU=y CONFIG_ARCH_MXC=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_RENESAS=y CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_SEATTLE=y CONFIG_ARCH_STRATIX10=y CONFIG_ARCH_SYNQUACER=y CONFIG_ARCH_TEGRA=y CONFIG_ARCH_SPRD=y CONFIG_ARCH_THUNDER=y CONFIG_ARCH_THUNDER2=y CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_VEXPRESS=y CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZX=y CONFIG_ARCH_ZYNQMP=y CONFIG_ARM64_VA_BITS_48=y CONFIG_SCHED_MC=y CONFIG_NUMA=y CONFIG_SECCOMP=y CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y CONFIG_XEN=y CONFIG_COMPAT=y CONFIG_HIBERNATION=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y CONFIG_ACPI_CPPC_CPUFREQ=m CONFIG_ARM_ARMADA_37XX_CPUFREQ=y CONFIG_ARM_SCPI_CPUFREQ=y CONFIG_ARM_TEGRA186_CPUFREQ=y CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_INTEL_STRATIX10_SERVICE=y CONFIG_TI_SCI_PROTOCOL=y CONFIG_EFI_CAPSULE_LOADER=y CONFIG_IMX_SCU=y CONFIG_IMX_SCU_PD=y CONFIG_ACPI=y CONFIG_ACPI_APEI=y CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_MEMORY_FAILURE=y CONFIG_ACPI_APEI_EINJ=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y CONFIG_CRYPTO_SHA512_ARM64_CE=m CONFIG_CRYPTO_SHA3_ARM64=m CONFIG_CRYPTO_SM3_ARM64_CE=m CONFIG_CRYPTO_GHASH_ARM64_CE=y CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRYPTO_AES_ARM64_BS=m CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_KSM=y CONFIG_MEMORY_FAILURE=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_CMA=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IPV6=m CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_NAT=m CONFIG_IP_NF_TARGET_MASQUERADE=m CONFIG_IP_NF_MANGLE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_NAT=m CONFIG_IP6_NF_TARGET_MASQUERADE=m CONFIG_BRIDGE=m CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y CONFIG_QRTR=m CONFIG_QRTR_SMD=m CONFIG_QRTR_TUN=m CONFIG_BPF_JIT=y CONFIG_BT=m CONFIG_BT_HIDP=m # CONFIG_BT_HS is not set # CONFIG_BT_LE is not set CONFIG_BT_LEDS=y # CONFIG_BT_DEBUGFS is not set CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_BCM=y CONFIG_CFG80211=m CONFIG_MAC80211=m CONFIG_MAC80211_LEDS=y CONFIG_RFKILL=m CONFIG_NET_9P=y CONFIG_NET_9P_VIRTIO=y CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCI_IOV=y CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_PCI_AARDVARK=y CONFIG_PCI_TEGRA=y CONFIG_PCIE_RCAR=y CONFIG_PCI_HOST_GENERIC=y CONFIG_PCI_XGENE=y CONFIG_PCIE_ALTERA=y CONFIG_PCIE_ALTERA_MSI=y CONFIG_PCI_HOST_THUNDER_PEM=y CONFIG_PCI_HOST_THUNDER_ECAM=y CONFIG_PCIE_ROCKCHIP_HOST=m CONFIG_PCI_LAYERSCAPE=y CONFIG_PCI_HISI=y CONFIG_PCIE_QCOM=y CONFIG_PCIE_ARMADA_8K=y CONFIG_PCIE_KIRIN=y CONFIG_PCIE_HISI_STB=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_HISILICON_LPC=y CONFIG_SIMPLE_PM_BUS=y CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_M25P80=y CONFIG_MTD_RAW_NAND=y CONFIG_MTD_NAND_DENALI_DT=y CONFIG_MTD_NAND_MARVELL=y CONFIG_MTD_NAND_QCOM=y CONFIG_MTD_SPI_NOR=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m CONFIG_VIRTIO_BLK=y CONFIG_BLK_DEV_NVME=m CONFIG_SRAM=y CONFIG_EEPROM_AT25=m # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y CONFIG_SCSI_HISI_SAS_PCI=y CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_QCOM=m CONFIG_SCSI_UFS_HISI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y CONFIG_AHCI_CEVA=y CONFIG_AHCI_MVEBU=y CONFIG_AHCI_XGENE=y CONFIG_AHCI_QORIQ=y CONFIG_SATA_SIL24=y CONFIG_SATA_RCAR=y CONFIG_PATA_PLATFORM=y CONFIG_PATA_OF_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_MACVLAN=m CONFIG_MACVTAP=m CONFIG_TUN=y CONFIG_VETH=m CONFIG_VIRTIO_NET=y CONFIG_AMD_XGBE=y CONFIG_NET_XGENE=y CONFIG_ATL1C=m CONFIG_MACB=y CONFIG_THUNDER_NIC_PF=y CONFIG_FEC=y CONFIG_HIX5HD2_GMAC=y CONFIG_HNS_DSAF=y CONFIG_HNS_ENET=y CONFIG_HNS3=y CONFIG_HNS3_HCLGE=y CONFIG_HNS3_ENET=y CONFIG_E1000E=y CONFIG_IGB=y CONFIG_IGBVF=y CONFIG_MVNETA=y CONFIG_MVPP2=y CONFIG_SKY2=y CONFIG_QCOM_EMAC=m CONFIG_RAVB=y CONFIG_SMC91X=y CONFIG_SMSC911X=y CONFIG_SNI_AVE=y CONFIG_SNI_NETSEC=y CONFIG_STMMAC_ETH=m CONFIG_MDIO_BUS_MUX_MMIOREG=y CONFIG_AT803X_PHY=m CONFIG_MARVELL_PHY=m CONFIG_MARVELL_10G_PHY=m CONFIG_MESON_GXL_PHY=m CONFIG_MICREL_PHY=y CONFIG_REALTEK_PHY=m CONFIG_ROCKCHIP_PHY=y CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m CONFIG_USB_LAN78XX=m CONFIG_USB_USBNET=m CONFIG_USB_NET_DM9601=m CONFIG_USB_NET_SR9800=m CONFIG_USB_NET_SMSC75XX=m CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_NET_PLUSB=m CONFIG_USB_NET_MCS7830=m CONFIG_ATH10K=m CONFIG_ATH10K_PCI=m CONFIG_BRCMFMAC=m CONFIG_MWIFIEX=m CONFIG_MWIFIEX_PCIE=m CONFIG_WL18XX=m CONFIG_WLCORE_SDIO=m CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_ADC=m CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_CROS_EC=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ATMEL_MXT=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PM8941_PWRKEY=y CONFIG_INPUT_HISI_POWERKEY=y # CONFIG_SERIO_SERPORT is not set CONFIG_SERIO_AMBAKMI=y CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_8250_OMAP=y CONFIG_SERIAL_8250_MT6577=y CONFIG_SERIAL_8250_UNIPHIER=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_MESON=y CONFIG_SERIAL_MESON_CONSOLE=y CONFIG_SERIAL_SAMSUNG=y CONFIG_SERIAL_SAMSUNG_CONSOLE=y CONFIG_SERIAL_TEGRA=y CONFIG_SERIAL_TEGRA_TCU=y CONFIG_SERIAL_IMX=y CONFIG_SERIAL_IMX_CONSOLE=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SERIAL_QCOM_GENI=y CONFIG_SERIAL_QCOM_GENI_CONSOLE=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_SERIAL_FSL_LPUART=y CONFIG_SERIAL_FSL_LPUART_CONSOLE=y CONFIG_SERIAL_MVEBU_UART=y CONFIG_SERIAL_DEV_BUS=y CONFIG_VIRTIO_CONSOLE=y CONFIG_IPMI_HANDLER=m CONFIG_IPMI_DEVICE_INTERFACE=m CONFIG_IPMI_SI=m CONFIG_TCG_TPM=y CONFIG_TCG_TIS_I2C_INFINEON=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_MUX_PCA954x=y CONFIG_I2C_BCM2835=m CONFIG_I2C_DESIGNWARE_PLATFORM=y CONFIG_I2C_GPIO=m CONFIG_I2C_IMX=y CONFIG_I2C_MESON=y CONFIG_I2C_MV64XXX=y CONFIG_I2C_PXA=y CONFIG_I2C_QUP=y CONFIG_I2C_RK3X=y CONFIG_I2C_SH_MOBILE=y CONFIG_I2C_TEGRA=y CONFIG_I2C_UNIPHIER_F=y CONFIG_I2C_RCAR=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_SPI=y CONFIG_SPI_ARMADA_3700=y CONFIG_SPI_BCM2835=m CONFIG_SPI_BCM2835AUX=m CONFIG_SPI_NXP_FLEXSPI=y CONFIG_SPI_MESON_SPICC=m CONFIG_SPI_MESON_SPIFC=m CONFIG_SPI_ORION=y CONFIG_SPI_PL022=y CONFIG_SPI_ROCKCHIP=y CONFIG_SPI_QUP=y CONFIG_SPI_S3C64XX=y CONFIG_SPI_SPIDEV=m CONFIG_SPI_SUN6I=y CONFIG_SPMI=y CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_MAX77620=y CONFIG_PINCTRL_IMX8MQ=y CONFIG_PINCTRL_IMX8QXP=y CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_MSM8916=y CONFIG_PINCTRL_MSM8994=y CONFIG_PINCTRL_MSM8996=y CONFIG_PINCTRL_MSM8998=y CONFIG_PINCTRL_QCS404=y CONFIG_PINCTRL_QDF2XXX=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_PINCTRL_SDM845=y CONFIG_GPIO_DWAPB=y CONFIG_GPIO_MB86S7X=y CONFIG_GPIO_PL061=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_UNIPHIER=y CONFIG_GPIO_XGENE=y CONFIG_GPIO_XGENE_SB=y CONFIG_GPIO_PCA953X=y CONFIG_GPIO_PCA953X_IRQ=y CONFIG_GPIO_MAX77620=y CONFIG_POWER_AVS=y CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_SBS=m CONFIG_BATTERY_BQ27XXX=y CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_RASPBERRYPI_HWMON=m CONFIG_SENSORS_INA2XX=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y CONFIG_THERMAL_EMULATION=y CONFIG_ROCKCHIP_THERMAL=m CONFIG_RCAR_THERMAL=y CONFIG_RCAR_GEN3_THERMAL=y CONFIG_ARMADA_THERMAL=y CONFIG_BCM2835_THERMAL=m CONFIG_BRCMSTB_THERMAL=m CONFIG_EXYNOS_THERMAL=y CONFIG_TEGRA_BPMP_THERMAL=m CONFIG_QCOM_TSENS=y CONFIG_UNIPHIER_THERMAL=y CONFIG_WATCHDOG=y CONFIG_ARM_SP805_WATCHDOG=y CONFIG_S3C2410_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_MESON_GXBB_WATCHDOG=m CONFIG_MESON_WATCHDOG=m CONFIG_RENESAS_WDT=y CONFIG_UNIPHIER_WATCHDOG=y CONFIG_BCM2835_WDT=y CONFIG_MFD_ALTERA_SYSMGR=y CONFIG_MFD_BD9571MWV=y CONFIG_MFD_AXP20X_I2C=y CONFIG_MFD_AXP20X_RSB=y CONFIG_MFD_CROS_EC=y CONFIG_MFD_CROS_EC_CHARDEV=m CONFIG_MFD_EXYNOS_LPASS=m CONFIG_MFD_HI6421_PMIC=y CONFIG_MFD_HI655X_PMIC=y CONFIG_MFD_MAX77620=y CONFIG_MFD_SPMI_PMIC=y CONFIG_MFD_RK808=y CONFIG_MFD_SEC_CORE=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_BD9571MWV=y CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_HI6421V530=y CONFIG_REGULATOR_HI655X=y CONFIG_REGULATOR_MAX77620=y CONFIG_REGULATOR_MAX8973=y CONFIG_REGULATOR_PFUZE100=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_QCOM_RPMH=y CONFIG_REGULATOR_QCOM_SMD_RPM=y CONFIG_REGULATOR_QCOM_SPMI=y CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_S2MPS11=y CONFIG_REGULATOR_VCTRL=m CONFIG_RC_CORE=m CONFIG_RC_DECODERS=y CONFIG_RC_DEVICES=y CONFIG_IR_MESON=m CONFIG_MEDIA_SUPPORT=m CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y # CONFIG_DVB_NET is not set CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_SUN6I_CSI=m CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m CONFIG_VIDEO_SAMSUNG_S5P_MFC=m CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m CONFIG_VIDEO_RENESAS_FCP=m CONFIG_VIDEO_RENESAS_VSP1=m CONFIG_DRM=m CONFIG_DRM_NOUVEAU=m CONFIG_DRM_EXYNOS=m CONFIG_DRM_EXYNOS5433_DECON=y CONFIG_DRM_EXYNOS7_DECON=y CONFIG_DRM_EXYNOS_DSI=y # CONFIG_DRM_EXYNOS_DP is not set CONFIG_DRM_EXYNOS_HDMI=y CONFIG_DRM_EXYNOS_MIC=y CONFIG_DRM_ROCKCHIP=m CONFIG_ROCKCHIP_ANALOGIX_DP=y CONFIG_ROCKCHIP_CDN_DP=y CONFIG_ROCKCHIP_DW_HDMI=y CONFIG_ROCKCHIP_DW_MIPI_DSI=y CONFIG_ROCKCHIP_INNO_HDMI=y CONFIG_DRM_RCAR_DU=m CONFIG_DRM_SUN4I=m CONFIG_DRM_SUN8I_DW_HDMI=m CONFIG_DRM_SUN8I_MIXER=m CONFIG_DRM_TEGRA=m CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_SII902X=m CONFIG_DRM_I2C_ADV7511=m CONFIG_DRM_VC4=m CONFIG_DRM_HISI_HIBMC=m CONFIG_DRM_HISI_KIRIN=m CONFIG_DRM_MESON=m CONFIG_DRM_PL111=m CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y CONFIG_BACKLIGHT_GENERIC=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_LP855X=m CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_HDA_TEGRA=m CONFIG_SND_HDA_CODEC_HDMI=m CONFIG_SND_SOC=y CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_MESON_AXG_SOUND_CARD=m CONFIG_SND_SOC_ROCKCHIP=m CONFIG_SND_SOC_ROCKCHIP_SPDIF=m CONFIG_SND_SOC_ROCKCHIP_RT5645=m CONFIG_SND_SOC_RK3399_GRU_SOUND=m CONFIG_SND_SOC_SAMSUNG=y CONFIG_SND_SOC_RCAR=m CONFIG_SND_SOC_AK4613=m CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m CONFIG_SND_SOC_PCM3168A_I2C=m CONFIG_SND_SOC_TAS571X=m CONFIG_SND_SIMPLE_CARD=m CONFIG_SND_AUDIO_GRAPH_CARD=m CONFIG_I2C_HID=m CONFIG_USB=y CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_TEGRA=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_EXYNOS=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_EXYNOS=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_RENESAS_USBHS=m CONFIG_USB_STORAGE=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_SUNXI=y CONFIG_USB_DWC3=y CONFIG_USB_DWC2=y CONFIG_USB_CHIPIDEA=y CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y CONFIG_USB_HSIC_USB3503=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y CONFIG_USB_RENESAS_USBHS_UDC=m CONFIG_USB_RENESAS_USB3=m CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ACPI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y CONFIG_MMC_SDHCI_OF_ESDHC=y CONFIG_MMC_SDHCI_CADENCE=y CONFIG_MMC_SDHCI_ESDHC_IMX=y CONFIG_MMC_SDHCI_TEGRA=y CONFIG_MMC_SDHCI_F_SDH30=y CONFIG_MMC_MESON_GX=y CONFIG_MMC_SDHCI_MSM=y CONFIG_MMC_SPI=y CONFIG_MMC_SDHI=y CONFIG_MMC_UNIPHIER=y CONFIG_MMC_DW=y CONFIG_MMC_DW_EXYNOS=y CONFIG_MMC_DW_HI3798CV200=y CONFIG_MMC_DW_K3=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SUNXI=y CONFIG_MMC_BCM2835=y CONFIG_MMC_SDHCI_XENON=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y CONFIG_LEDS_TRIGGER_DISK=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_PANIC=y CONFIG_EDAC=y CONFIG_EDAC_GHES=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m CONFIG_RTC_DRV_RX8581=m CONFIG_RTC_DRV_S5M=y CONFIG_RTC_DRV_DS3232=y CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_CROS_EC=y CONFIG_RTC_DRV_S3C=y CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_ARMADA38X=y CONFIG_RTC_DRV_TEGRA=y CONFIG_RTC_DRV_IMX_SC=m CONFIG_RTC_DRV_XGENE=y CONFIG_DMADEVICES=y CONFIG_FSL_EDMA=y CONFIG_DMA_BCM2835=m CONFIG_K3_DMA=y CONFIG_MV_XOR=y CONFIG_MV_XOR_V2=y CONFIG_PL330_DMA=y CONFIG_TEGRA20_APB_DMA=y CONFIG_QCOM_BAM_DMA=y CONFIG_QCOM_HIDMA_MGMT=y CONFIG_QCOM_HIDMA=y CONFIG_RCAR_DMAC=y CONFIG_RENESAS_USB_DMAC=m CONFIG_VFIO=y CONFIG_VFIO_PCI=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y CONFIG_XEN_GNTDEV=y CONFIG_XEN_GRANT_DEV_ALLOC=y CONFIG_CROS_EC_I2C=y CONFIG_CROS_EC_SPI=y CONFIG_COMMON_CLK_RK808=y CONFIG_COMMON_CLK_SCPI=y CONFIG_COMMON_CLK_CS2000_CP=y CONFIG_COMMON_CLK_S2MPS11=y CONFIG_CLK_QORIQ=y CONFIG_COMMON_CLK_PWM=y CONFIG_CLK_IMX8MQ=y CONFIG_CLK_IMX8QXP=y CONFIG_TI_SCI_CLK=y CONFIG_COMMON_CLK_QCOM=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_QCOM_CLK_RPMH=y CONFIG_IPQ_GCC_8074=y CONFIG_MSM_GCC_8916=y CONFIG_MSM_GCC_8994=y CONFIG_MSM_MMCC_8996=y CONFIG_MSM_GCC_8998=y CONFIG_QCS_GCC_404=y CONFIG_SDM_GCC_845=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y CONFIG_ARM_MHU=y CONFIG_IMX_MBOX=y CONFIG_PLATFORM_MHU=y CONFIG_BCM2835_MBOX=y CONFIG_TI_MESSAGE_MANAGER=y CONFIG_QCOM_APCS_IPC=y CONFIG_ROCKCHIP_IOMMU=y CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_ARM_SMMU=y CONFIG_ARM_SMMU_V3=y CONFIG_QCOM_IOMMU=y CONFIG_REMOTEPROC=m CONFIG_QCOM_Q6V5_MSS=m CONFIG_QCOM_Q6V5_PAS=m CONFIG_QCOM_SYSMON=m CONFIG_RPMSG_QCOM_GLINK_RPM=y CONFIG_RPMSG_QCOM_GLINK_SMEM=m CONFIG_RPMSG_QCOM_SMD=y CONFIG_RASPBERRYPI_POWER=y CONFIG_QCOM_COMMAND_DB=y CONFIG_QCOM_GENI_SE=y CONFIG_QCOM_GLINK_SSR=m CONFIG_QCOM_RPMH=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD_RPM=y CONFIG_QCOM_SMP2P=y CONFIG_QCOM_SMSM=y CONFIG_ARCH_R8A774A1=y CONFIG_ARCH_R8A774C0=y CONFIG_ARCH_R8A7795=y CONFIG_ARCH_R8A7796=y CONFIG_ARCH_R8A77965=y CONFIG_ARCH_R8A77970=y CONFIG_ARCH_R8A77980=y CONFIG_ARCH_R8A77990=y CONFIG_ARCH_R8A77995=y CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y CONFIG_ARCH_TEGRA_186_SOC=y CONFIG_ARCH_TEGRA_194_SOC=y CONFIG_ARCH_K3_AM6_SOC=y CONFIG_SOC_TI=y CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_EXTCON_USB_GPIO=y CONFIG_EXTCON_USBC_CROS_EC=y CONFIG_MEMORY=y CONFIG_IIO=y CONFIG_EXYNOS_ADC=y CONFIG_ROCKCHIP_SARADC=m CONFIG_IIO_CROS_EC_SENSORS_CORE=m CONFIG_IIO_CROS_EC_SENSORS=m CONFIG_IIO_CROS_EC_LIGHT_PROX=m CONFIG_IIO_CROS_EC_BARO=m CONFIG_PWM=y CONFIG_PWM_BCM2835=m CONFIG_PWM_CROS_EC=m CONFIG_PWM_MESON=m CONFIG_PWM_RCAR=m CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y CONFIG_PWM_SUN4I=m CONFIG_PWM_TEGRA=m CONFIG_RESET_TI_SCI=y CONFIG_PHY_XGENE=y CONFIG_PHY_SUN4I_USB=y CONFIG_PHY_HI6220_USB=y CONFIG_PHY_HISTB_COMBPHY=y CONFIG_PHY_HISI_INNO_USB2=y CONFIG_PHY_MVEBU_CP110_COMPHY=y CONFIG_PHY_QCOM_QMP=m CONFIG_PHY_QCOM_USB_HS=y CONFIG_PHY_RCAR_GEN3_PCIE=y CONFIG_PHY_RCAR_GEN3_USB2=y CONFIG_PHY_RCAR_GEN3_USB3=m CONFIG_PHY_ROCKCHIP_EMMC=y CONFIG_PHY_ROCKCHIP_INNO_HDMI=m CONFIG_PHY_ROCKCHIP_INNO_USB2=y CONFIG_PHY_ROCKCHIP_PCIE=m CONFIG_PHY_ROCKCHIP_TYPEC=y CONFIG_PHY_UNIPHIER_USB2=y CONFIG_PHY_UNIPHIER_USB3=y CONFIG_PHY_TEGRA_XUSB=y CONFIG_HISI_PMU=y CONFIG_QCOM_L2_PMU=y CONFIG_QCOM_L3_PMU=y CONFIG_QCOM_QFPROM=y CONFIG_ROCKCHIP_EFUSE=y CONFIG_UNIPHIER_EFUSE=y CONFIG_MESON_EFUSE=m CONFIG_FPGA=y CONFIG_FPGA_MGR_STRATIX10_SOC=m CONFIG_FPGA_BRIDGE=m CONFIG_ALTERA_FREEZE_BRIDGE=m CONFIG_FPGA_REGION=m CONFIG_OF_FPGA_REGION=m CONFIG_TEE=y CONFIG_OPTEE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA=y CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=m CONFIG_CUSE=m CONFIG_OVERLAY_FS=m CONFIG_VFAT_FS=y CONFIG_HUGETLBFS=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_ROOT_NFS=y CONFIG_9P_FS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_SECURITY=y CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=32 CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_FTRACE is not set CONFIG_MEMTEST=y
在linux内核根目录下执行如下命令,执行完之后会在内核根目录下生成默认配置文件.config:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# make defconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o HOSTCC scripts/kconfig/confdata.o HOSTCC scripts/kconfig/expr.o LEX scripts/kconfig/lexer.lex.c YACC scripts/kconfig/parser.tab.h HOSTCC scripts/kconfig/lexer.lex.o YACC scripts/kconfig/parser.tab.c HOSTCC scripts/kconfig/parser.tab.o HOSTCC scripts/kconfig/preprocess.o HOSTCC scripts/kconfig/symbol.o HOSTLD scripts/kconfig/conf *** Default configuration is based on 'defconfig' # # configuration written to .config #
1.4 内核裁切
我们可以通过make menuconfig配置内核支持的功能:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# make menuconfig
打开如下页面:
1.4.1 支持设备树
实际上在linux 5.2.8版本内核已经把设备树作为默认配置项了,因此也不需要我们配置了。内核在启动时,通过arch/arm/mach-rockchip/rockchip.c文件中的dt_compat数组中的信息和设备树中的compatible进行匹配,以此来找到相应单板文件;
static const char * const rockchip_board_dt_compat[] = { "rockchip,rk2928", "rockchip,rk3066a", "rockchip,rk3066b", "rockchip,rk3188", "rockchip,rk3228", "rockchip,rk3288", "rockchip,rv1108", NULL, }; DT_MACHINE_START(ROCKCHIP_DT, "Rockchip (Device Tree)") .l2c_aux_val = 0, .l2c_aux_mask = ~0, .init_time = rockchip_timer_init, .dt_compat = rockchip_board_dt_compat, .init_machine = rockchip_dt_init, MACHINE_END
不过不幸的是,该文件中默认并没有rockchip,rk33399。
1.4.2 支持NFS文件系统
使用NFS作为根文件系统,因为文件系统在宿主机中,这样在修改文件系统就非常方便,主要用于开发阶段使用。
File systems ---> [*] Network File Systems ---> <*> NFS client support for NFS version 4
勾选NFS client support for NFS version 4。
1.4.3 配置uevent helper
配置Support for uevent helper;
Device Drivers ---> Generic Driver Options ---> [*] Support for uevent helper (/sbin/mdev) path to uevent helper (NEW)
该选项的作用是启用uevent helper程序的支持。uevent是内核与用户空间之间通信的一种方式,当内核检测到新的设备时,会生成一个uevent来通知用户空间,使得用户空间能够及时响应设备插拔事件,并做出相应的处理。其中, uevent helper程序就是在接收到uevent后执行的用户空间程序,用来完成设备的热插拔处理。
在内核中,CONFIG_UEVENT_HELPER=y 的设定可以确保uevent helper程序能够被编译到内核中,从而能够正常地接收并响应uevent事件。
path to uevent helper 配置为/sbin/mdev;即指定uevent helper程序为/sbin.mdev。
具体参考:dev下无法生成节点的分析思路和解决方法及原理。
1.4.4 保存配置
保存配置:
存档:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# mv rk3399_defconfig ./arch/arm64/configs/
重新配置内核:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# make rk3399_defconfig
1.5 编译内核
1.5.1 编译内核
在linux内核根目录下执行如下命令:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# make -j8 HOSTCC scripts/extract-cert scripts/extract-cert.c:21:10: fatal error: openssl/bio.h: 没有那个文件或目录 21 | #include <openssl/bio.h> | ^~~~~~~~~~~~~~~ compilation terminated. make[1]: *** [scripts/Makefile.host:95:scripts/extract-cert] 错误 1 make: *** [Makefile:1204:scripts] 错误 2 make: *** 正在等待未完成的任务....
如果出现如上错误,安装libssl-dev即可:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# sudo apt install libssl-dev
这个编译属实有点久,如果可以的话,尽量裁切掉一些没用的驱动。
编译完成后会在linux根目录下生成vmlinux文件,elf格式:这个文件属实有点大117M,真是惊呆了;
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# ll vmlinux -rwxr-xr-x 1 root root 121809768 May 17 11:18 vmlinux* root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# du -sh vmlinux 117M vmlinux
此外,在arch/arm64/boot/文件夹下生成Image镜像文件,以及设备树dst/rockchip/xxx.dtb文件;
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# ll arch/arm64/boot 总用量 44032 drwxr-xr-x 3 root root 4096 May 16 11:28 ./ drwxr-xr-x 14 root root 4096 May 16 11:15 ../ drwxr-xr-x 33 root root 4096 May 16 10:27 dts/ -rw-r--r-- 1 root root 55 May 16 10:27 .gitignore -rw-r--r-- 1 root root 33616384 May 16 11:27 Image -rw-r--r-- 1 root root 134 May 16 11:27 .Image.cmd -rw-r--r-- 1 root root 11617499 May 16 11:28 Image.gz -rw-r--r-- 1 root root 101 May 16 11:28 .Image.gz.cmd -rw-r--r-- 1 root root 1562 May 16 10:27 install.sh -rw-r--r-- 1 root root 960 May 16 10:27 Makefile root@zhengyang:/work/sambashare/rk3399/linux-5.2.8/arch/arm64# cd arch/arm64/boot root@zhengyang:/work/sambashare/rk3399/linux-5.2.8/arch/arm64/boot# ls dts/rockchip/*rk3399*.dtb dts/rockchip/rk3399-evb.dtb dts/rockchip/rk3399-gru-scarlet-kd.dtb dts/rockchip/rk3399-rock960.dtb dts/rockchip/rk3399-ficus.dtb dts/rockchip/rk3399-nanopc-t4.dtb dts/rockchip/rk3399-rock-pi-4.dtb dts/rockchip/rk3399-firefly.dtb dts/rockchip/rk3399-nanopi-m4.dtb dts/rockchip/rk3399-rockpro64.dtb dts/rockchip/rk3399-gru-bob.dtb dts/rockchip/rk3399-nanopi-neo4.dtb dts/rockchip/rk3399-roc-pc.dtb dts/rockchip/rk3399-gru-kevin.dtb dts/rockchip/rk3399-orangepi.dtb dts/rockchip/rk3399-sapphire.dtb dts/rockchip/rk3399-gru-scarlet-inx.dtb dts/rockchip/rk3399-puma-haikou.dtb dts/rockchip/rk3399-sapphire-excavator.dtb
1.5.2 编译dts
如果需要单独编译设备树,在linux内核根目录执行如下命令:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# make rockchip/rk3399-evb.dts dtbs V=1
即可把arch/arm64/boot/dts/rockchip里的dts文件编译成dtb文件。
1.6 生成boot.img
1.6.1 内核镜像文件介绍
linux内核常用的镜像文件格式有以下几种:
- vmlinux:linux内核编译出来的原始的内核文件,elf格式。该文件包含了符号表、重定位等信息,可以用来调试,但不能直接引导linux系统启动;可以使用arm-linx-readelf -h vmlinux查看文件信息;
- Image:linux内核编译时,使用arm-linux-objcopy处理vmlinux后生成的二进制文件。该文件是raw binary二进制文件,bin文件是将elf文件中的代码段,数据段,还有一些自定义的段抽取出来做成的一个内存的镜像,可直接引导linux系统启动;
- zImage:使用gzip压缩Image后,使用arm-linux-objcopy命令生成的linux内核镜像。该文件一般作为uboot的引导文件;
- uImage:在zImage前面增加一个64字节的头,描述镜像文件类型,加载位置,大小等信息。该文件是老版本uboot专用的引导文件,比如我们熟悉的Mini2440使用的就是这种;
下图展示了不同类型的linux镜像生成过程:
1.6.2 Distro
由于Rockchp官方uboot使用distro引导,因此我们需要制作一个包含内核镜像和设备树的启动分区。
首先,创建一个名为boot的文件夹:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# mkdir boot
然后,将设备树二进制文件复制到该文件夹中,这里我们和uboot移植一样,选择官方的评估板对应的设备树文件rk3399-evb.dtb:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# cp arch/arm64/boot/dts/rockchip/rk3399-evb.dtb boot/rk3399.dtb
接着,将内核镜像复制到该文件夹中:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# cp arch/arm64/boot/Image boot/
为了实现distro 引导,我们需要在启动分区中添加extlinux引导程序以及相应的配置文件。具体步骤如下:
(1) 首先,创建一个名为extlinux的文件夹,在其中创建一个名为extlinux.conf的文件:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# mkdir boot/extlinux root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# vim boot/extlinux/extlinux.conf
(2) 然后,在该文件中编写配置信息,指定内核镜像和设备树的路径,以及其它启动参数。以下是一个示例配置文件:
label rockchip-kernel-5.2.8 kernel /Image fdt /rk3399.dtb append earlycon=uart8250,mmio32,0xff1a0000 root=PARTUUID=B921B045-1D rootwait rootfstype=ext4 init=/sbin/init
我们需要根据自己的开发板配置串口,根文件系统所在的分区来进行修改(参考Rockchip Linux的根文件系统分区定义)。
在所有这些文件都准备好之后,boot文件夹结构如下:
boot
├── extlinux
│ └── extlinux.conf
├── Image
└── rk3399-evb.dtb
1.6.3 ext2
使用genext2fs工具可以生成一个ext2文件系统镜像文件。在使用genext2fs命令时,需要指定生成文件系统的大小、块大小、 inode大小等参数,以及输出的镜像文件名称和所在路径。
执行以下命令,将boot文件夹中的文件和目录打包成一个ext2文件系统镜像:
root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# sudo apt-get install genext2fs root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# genext2fs -b 32768 -B $((64*1024*1024/32768)) -d boot/ -i 8192 -U boot.img root@zhengyang:/work/sambashare/rk3399/linux-5.2.8# ll boot.img -rw-r--r-- 1 root root 33554432 May 17 05:17 boot.img
其中:
- -b :表示文件系统块的数量;
- -B : 表示文件系统块的大小,单位为字节;
- -d :从指定目录开始创建文件系统
- -i 8192;每个inode使用的字节数;
- -U:选项表示创建一个唯一的文件系统UUID;
这里我们设置了32768个块,每个块大小为64*1024*1024/32768,所以文件系统总大小为64MB,足够放下boot文件夹内的所有文件。
二、ramdisk根文件系统制作
在Mini2440之linux根文件系统yaffs2移植文章中我们已经介绍了根文件系统的制作,不过当时是制作的是yaffs2类型的根文件系统,适用于外部设备Nand Flash,这一节我们将制作ramdisk类型的根文件系统。制作流程基本是一致的。
2.1 编译、安装、配置 busybox
2.1.1 下载源码
根文件系统是根据busybox来制作的。下载地址:https://busybox.net/downloads/。
这里我们就以1.36.0版本为例进行编译安装介绍:
注意:一般你使用什么版本的交叉编译器来编译linux内核时,文件系统中的所有程序也要使用同样的交叉编译器来编译。
下载完成后解压:
root@zhengyang:/work/sambashare/rk3399# wget https://busybox.net/downloads/busybox-1.36.0.tar.bz2 tar root@zhengyang:/work/sambashare/rk3399# tar -jxf busybox-1.36.0.tar.bz2
2.1.2 配置busybox
在路径busybox-1.36.0下运行如下命令,使用默认配置:
root@zhengyang:/work/sambashare/rk3399# cd busybox-1.36.0/ root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# make defconfig
然后进入图像化配置页面,修改配置 :
root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# make menuconfig
进入Busybox Settings,配置如下参数:
Settings ---> (/usr/local/arm/12.2.1/bin/arm-linux-) Cross compile prefix ( -march=armv8-a) additional CFLAGS [ ] Build static binary (no shared libs) [*] Build Shared libbusybox
编译方式有两种:
- 第一种是以静态方式编译,即生成的busybox不需要动态库的支持就能运行。这样做我们就不需要部署动态库了,缺点就是自己写的程序在这个根文件系统中是不能运行的,因为缺少动态库库的支持。
- 第二种方式使用动态编译,这样的话我们就需要部署动态库了,在linux动态库文件是以so为后缀,而windows下文件是以dll为后缀。
这里我们指定了arm-linux-gcc 12.2.1编译器的路径,这里就不具体介绍编译器如何安装了。
继续配置:
Linux System Utilities ---> [] nsenter Coreutils ---> [] sync Miscellaneous Utilities ---> 自己选择 Networking Utilities ---> 自己选择 Linux System Utilities ---> [*] hexdump
2.1.3 编译安装
运行命令:
root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# make
然后查看当前路径下是否存在busybox:
root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# ll busybox -rwxr-xr-x 1 root root 1119768 May 19 19:28 busybox*
执行make install:
root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# make install
make install的目的就是将编译生成的可执行程序及其依赖的库文件、配置文件、头文件安装到当前系统中指定(一般都可以自己指定安装到哪个目录下,如果不指定一般都有个默认目录)的目录下,默认被安装到_install 目录下:
root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# ll _install/ 总用量 92 drwxr-xr-x 6 root root 4096 May 19 19:29 ./ drwxr-xr-x 38 root root 4096 May 19 19:29 ../ drwxr-xr-x 2 root root 4096 May 19 19:29 bin/ drwxr-xr-x 2 root root 4096 May 19 19:29 lib64/ -rwxr-xr-x 1 root root 67392 May 19 19:28 linuxrc* drwxr-xr-x 2 root root 4096 May 19 19:29 sbin/ drwxr-xr-x 4 root root 4096 May 19 19:29 usr/
里面有5个文件:bin、sbin、usr这三个目录里都是二进制命令工具,lib64里面是库文件,这还不足以构成 一个可用的根文件系统,必须进行其它完善工作,才能构建一个可用的根文件系统。
2.2 构建根文件系统
新建一个目录用来存放制作的根文件系统,可以命名为rootfs。将利用BusyBox生成的二进制文件及目录,即_install目录下的所有文件及目录复制到rootfs目录下。
root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# mkdir ../rootfs root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# cp -a _install/* ../rootfs/
2.2.1 添加库文件
切换到rootfs路径下:
root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# cd ../rootfs
找到交叉编译工具里的动态库复制到lib目录下:
root@zhengyang:/work/sambashare/rk3399/rootfs# mkdir lib root@zhengyang:/work/sambashare/rk3399/rootfs# cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/lib/*so* ./lib/ root@zhengyang:/work/sambashare/rk3399/rootfs# cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/lib64/*so* ./lib64/ root@zhengyang:/work/sambashare/rk3399/rootfs# cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/usr/lib/*so* ./lib/ root@zhengyang:/work/sambashare/rk3399/rootfs# cp -a /usr/local/arm/12.2.1/aarch64-none-linux-gnu/libc/usr/lib64/*so* ./lib64/
-a保留权限,复制软链接本身,递归复制。
查看库文件:
root@zhengyang:/work/sambashare/rk3399/rootfs# ls ./lib ld-linux-aarch64.so.1 libinproctrace.so root@zhengyang:/work/sambashare/rk3399/rootfs# ls ./lib64/ libanl.so libcrypt.so.1 libhwasan.so.0.0.0 libnss_db.so.2 libstdc++.so.6.0.30-gdb.py libanl.so.1 libc.so libitm.so libnss_dns.so.2 libthread_db.so libasan.so libc.so.6 libitm.so.1 libnss_files.so.2 libthread_db.so.1 libasan.so.8 libdl.so.2 libitm.so.1.0.0 libnss_hesiod.so libtsan.so libasan.so.8.0.0 libgcc_s.so liblsan.so libnss_hesiod.so.2 libtsan.so.2 libatomic.so libgcc_s.so.1 liblsan.so.0 libpcprofile.so libtsan.so.2.0.0 libatomic.so.1 libgfortran.so liblsan.so.0.0.0 libpthread.so.0 libubsan.so libatomic.so.1.2.0 libgfortran.so.5 libmemusage.so libresolv.a libubsan.so.1 libBrokenLocale.so libgfortran.so.5.0.0 libm.so libresolv.so libubsan.so.1.0.0 libBrokenLocale.so.1 libgomp.so libm.so.6 libresolv.so.2 libutil.so.1 libbusybox.so.1.36.0 libgomp.so.1 libnsl.so.1 librt.so.1 libc_malloc_debug.so libgomp.so.1.0.0 libnss_compat.so libstdc++.so libc_malloc_debug.so.0 libhwasan.so libnss_compat.so.2 libstdc++.so.6 libcrypt.so libhwasan.so.0 libnss_db.so libstdc++.so.6.0.30
这里只是拷贝动态链接库。一般开发程序使用动态编译需要板子上动态库的支持才能运行,所以拷贝动态库。
2.2.2 构建etc目录
初始化配置脚本放在在/etc目录下,用于系统启动所需的初始化配置脚本。BusyBox提供了一些初始化范例脚本,在examples/bootfloppy/etc/目录下:
root@zhengyang:/work/sambashare/rk3399# cd busybox-1.36.0/ root@zhengyang:/work/sambashare/rk3399/busybox-1.36.0# ll examples/bootfloppy/etc/ 总用量 24 drwxr-xr-x 3 root root 4096 Jan 3 22:17 ./ drwxr-xr-x 3 root root 4096 Jan 3 22:17 ../ -rw-r--r-- 1 root root 33 Jan 3 22:17 fstab drwxr-xr-x 2 root root 4096 Jan 3 22:17 init.d/ -rw-r--r-- 1 root root 100 Jan 3 22:17 inittab -rw-r--r-- 1 root root 133 Jan 3 22:17 profile
在rootfs目录,创建etc文件夹:
root@zhengyang:/work/sambashare/rk3399/rootfs# mkdir etc
将这些配置文件复制到新制作的根文件系统etc目录下。
root@zhengyang:/work/sambashare/rk3399/rootfs# cp -a ../busybox-1.36.0/examples/bootfloppy/etc/* ./etc root@zhengyang:/work/sambashare/rk3399/rootfs# ll etc 总用量 24 drwxr-xr-x 3 root root 4096 May 19 20:24 ./ drwxr-xr-x 8 root root 4096 May 19 20:23 ../ -rw-r--r-- 1 root root 33 Jan 3 22:17 fstab drwxr-xr-x 2 root root 4096 Jan 3 22:17 init.d/ -rw-r--r-- 1 root root 100 Jan 3 22:17 inittab -rw-r--r-- 1 root root 133 Jan 3 22:17 profile
2.2.3. 修改/etc/inittab文件
/etc/inittab文件是init进程解析的配置文件,通过这个配置文件决定执行哪个进程,何时执行。将文件修改为:
# 系统启动时 ::sysinit:/etc/init.d/rcS # 系统启动按下Enter键时 ::askfirst:-/bin/sh # 按下Ctrl+Alt+Del键时 ::ctrlaltdel:/sbin/reboot # 系统关机时 ::shutdown:/sbin/swapoff -a ::shutdown:/bin/umount -a -r # 系统重启时 ::restart:/sbin/init
以上内容定义了系统启动时,关机时,重启时,按下Ctrl+Alt+Del键时执行的进程。
2.2.4 修改/etc/init.d/rcS文件
#!/bin/sh # 挂载 /etc/fstab 中定义的所有文件系统 /bin/mount -a # 挂载虚拟的devpts文件系统用于用于伪终端设备 /bin/mkdir -p /dev/pts /bin/mount -t devpts devpts /dev/pts # 使用mdev动态管理u盘和鼠标等热插拔设备 /bin/echo /sbin/mdev > /proc/sys/kernel/hotplug # 扫描并创建节点 /sbin/mdev -s
修改init.d文件权限:
root@zhengyang:/work/sambashare/rk3399/rootfs# chmod -R 777 etc/init.d/*
2.2.5 修改/etc/fstab
/etc/fstab文件存放的是文件系统信息。在系统启动后执行/etc/init.d/rcS文件里/bin/mount -a命令时,自动挂载这些文件系统。
# <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 tmpfs /dev tmpfs defaults 0 0
这里我们挂载的文件系统有三个proc、sysfs和tmpfs,在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们需要添加tmpfs的支持。
2.2.6 修改/etc/profile文件
/etc/profile文件作用是设置环境变量,每个用户登录时都会运行它,将文件内容修改为:
# 主机名 export HOSTNAME=zy # 用户名 export USER=root # 用户目录 export HOME=/root # 终端默认提示符 export PS1="[$USER@$HOSTNAME:$PWD]# " # 环境变量 export PATH=/bin:/sbin:/usr/bin:/usr/sbin # 动态库路径 export LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
2.2.7 构建dev目录
在rootfs目录,创建dev文件夹:
root@zhengyang:/work/sambashare/rk3399/rootfs# mkdir dev
创建终端文件:
root@zhengyang:/work/sambashare/rk3399/rootfs# sudo mknod dev/console c 5 1 root@zhengyang:/work/sambashare/rk3399/rootfs# sudo mknod dev/null c 1 3
2.2.8 构建其他文件
root@zhengyang:/work/sambashare/rk3399/rootfs# mkdir mnt proc tmp sys root root@zhengyang:/work/sambashare/rk3399/rootfs# ll 总用量 124 drwxr-xr-x 14 root root 4096 May 19 20:33 ./ drwxr-xr-x 12 root root 4096 May 19 20:15 ../ drwxr-xr-x 2 root root 4096 May 19 19:29 bin/ drwxr-xr-x 2 root root 4096 May 19 20:33 dev/ drwxr-xr-x 3 root root 4096 May 19 20:32 etc/ drwxr-xr-x 2 root root 4096 May 19 20:20 lib/ drwxr-xr-x 2 root root 4096 May 19 20:21 lib64/ -rwxr-xr-x 1 root root 67392 May 19 19:28 linuxrc* drwxr-xr-x 2 root root 4096 May 19 20:33 mnt/ drwxr-xr-x 2 root root 4096 May 19 20:33 proc/ drwxr-xr-x 2 root root 4096 May 19 20:33 root/ drwxr-xr-x 2 root root 4096 May 19 19:29 sbin/ drwxr-xr-x 2 root root 4096 May 19 20:33 sys/ drwxr-xr-x 2 root root 4096 May 19 20:33 tmp/ drwxr-xr-x 4 root root 4096 May 19 19:29 usr/
2.3 制作根文件系统镜像
建立根文件系统挂载点:
root@zhengyang:/work/sambashare/rk3399/rootfs# mkdir /mnt/ramdisk
建立大小为 0x8000000的根文件系统:
root@zhengyang:/work/sambashare/rk3399/rootfs# mke2fs -vm0 /dev/ram 0x8000000
细节中打印的细节信息中包括块的个数、块的大小、结点个数等信息。
挂载根文件系统:
root@zhengyang:/work/sambashare/rk3399/rootfs# mount -t ext2 /dev/ram /mnt/ramdisk
对文件系统进行操作,将制作的文件系统复制到挂载点:
root@zhengyang:/work/sambashare/rk3399/rootfs# cp -af /work/sambashare/rk3399/rootfs/* /mnt/ramdisk
退出/mnt/ramdisk 目录才能进行卸载,卸载文件:
root@zhengyang:/work/sambashare/rk3399/rootfs# ll /mnt/ramdisk/ 总用量 144 drwxr-xr-x 15 root root 4096 May 19 20:45 ./ drwxr-xr-x 4 root root 4096 May 19 20:34 ../ drwxr-xr-x 2 root root 4096 May 19 19:29 bin/ drwxr-xr-x 2 root root 4096 May 19 20:33 dev/ drwxr-xr-x 3 root root 4096 May 19 20:32 etc/ drwxr-xr-x 2 root root 4096 May 19 20:20 lib/ drwxr-xr-x 2 root root 4096 May 19 20:21 lib64/ -rwxr-xr-x 1 root root 67392 May 19 19:28 linuxrc* drwx------ 2 root root 16384 May 19 20:44 lost+found/ drwxr-xr-x 2 root root 4096 May 19 20:33 mnt/ drwxr-xr-x 2 root root 4096 May 19 20:33 proc/ drwxr-xr-x 2 root root 4096 May 19 20:33 root/ drwxr-xr-x 2 root root 4096 May 19 19:29 sbin/ drwxr-xr-x 2 root root 4096 May 19 20:33 sys/ drwxr-xr-x 2 root root 4096 May 19 20:33 tmp/ drwxr-xr-x 4 root root 4096 May 19 19:29 usr/ root@zhengyang:/work/sambashare/rk3399/rootfs# umount /mnt/ramdisk root@zhengyang:/work/sambashare/rk3399/rootfs# ll /mnt/ramdisk/ 总用量 8 drwxr-xr-x 2 root root 4096 May 19 20:34 ./ drwxr-xr-x 4 root root 4096 May 19 20:34 ../
文件系统生成:
root@zhengyang:/work/sambashare/rk3399/rootfs# dd if=/dev/ram of=ramdisk bs=1M count=100
制作文件系统映像:
root@zhengyang:/work/sambashare/rk3399/rootfs# gzip -v9 ramdisk ramdisk: 99.9% -- replaced with ramdisk.gz root@zhengyang:/work/sambashare/rk3399/rootfs# ll ramdisk.gz -rw-r--r-- 1 root root 134661 May 19 20:47 ramdisk.gz
生成的映像文件为 ramdisk,压缩后为 ramdisk.gz。
二、烧录内核
5.1 准备镜像
我们按照之前的流程得到了如下文件idbloader.img、u-boot.itb,boot.img、rootfs.ext3。关于uboot镜像参考之前的文章:Rockchip RK3399 - TPL/SPL方式加载uboot。
按照Rockchip官方要求将:
- idbloader.img烧录到eMMC的0x40扇区;
- u-boot.itb烧录到0x4000扇区;
- boot.imgb烧录到0x8000扇区;
我们需要将boot.img拷贝到rkdeveloptool路径下:
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# cp ../linux-5.2.8/boot.img ./
5.2 进入MASKROM升级模式
NanoPC-T4开发板如需进入MASKROM升级模式,需要进入如下操作:
- 将开发板连接上电源,并且连接Type-C数据线到PC;
- 按住BOOT键再长按Power键开机(保持按下BOOT键5秒以上),将强制进入MASKROM模式。
一般电脑识别到USB连接,都会发出声音。或者观察虚拟机右下角是否突然多个USB设备:右键点击链接;
5.3 烧录
使用下载引导命令去使目标机器初始化DDR与运行usbplug(初始化DDR的原因是由于升级需要很大的内存,所以需要使用到DDR);
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool db rk3399_loader_v1.27.126.bin Downloading bootloader succeeded.
由于BootROM启动会将rk3399_loader_v1.27.126.bin将在到内部SRAM中,然后跳转到ddr.bin代码进行DDR的初始化,ddr.bin执行之后会回跳到BootROM程序,BootROM程序继续加载usbplug.bin,由usbplug.bin完成程序的下载以及烧录到eMMC。
使用wl命令烧写镜像到目标机器的eMMC,需要注意的是访问DDR所需的所有其他命令都应在使用db命令之后才能使用;
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool wl 0x40 idbloader.img Write LBA from file (100%) root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool wl 0x4000 u-boot.itb Write LBA from file (100%) root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool wl 0x8000 boot.img root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool wl 0x40000 rootfs.ext3 root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool rd
在烧写镜像完成后使用rd命令重启目标机器:
root@zhengyang:/work/sambashare/rk3399/rkdeveloptool# rkdeveloptool rd
Reset Device OK.
重启开发板,在倒计时执行完之前,按CTRL+C即可进入uboot命令行。使用以下命令从默认分区表中写入gpt表:
=> gpt write mmc 0 $partitions
Writing GPT: success!
其中,mmc 0表示eMMC设备编号为0,$partitions表示分区表的路径。
使用以下命令验证gpt表是否成功写入:
=> gpt verify mmc 0 $partitions
Verify GPT: success!
参考文章
[1] Rockchip Kernel
[2] 嵌入式ARM64 Linux内核编译及根文件系统构建
[5] Roclchip Partitions
[6] 在rk3399(rockpi 4b)上运行linux-5.3的mainline内核
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!