linux设备树-linux内核设备树移植(一)
目录
----------------------------------------------------------------------------------------------------------------------------
内核版本:linux 5.2.8
根文件系统:busybox 1.25.0
u-boot:2016.05
----------------------------------------------------------------------------------------------------------------------------
一、linux内核启动
我们回顾一下uboot引导linux内核启动过程, uboot通过执行bootcmd命令启动内核:
bootcmd="nand read 0x30000000 kernel; bootm 0x30000000"
uboot首先将内核镜像从NAND拷贝到内存地址0x30000000,然后执行bootm 0x30000000命令。
1.1 bootm命令
bootm这个命令用于启动一个操作系统映射,实际上调用的是do_bootm_linux函数,还函数位于arch/arm/lib/bootm.c文件:
/* Main Entry point for arm bootm implementation * * Modeled after the powerpc implementation * DIFFERENCE: Instead of calling prep and go at the end * they are called if subcommand is equal 0. */ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) { /* No need for those on ARM */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) // 不执行 return -1; if (flag & BOOTM_STATE_OS_PREP) { // 执行 boot_prep_linux(images); return 0; } if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { // 执行 boot_jump_linux(images, flag); return 0; } boot_prep_linux(images); boot_jump_linux(images, flag); return 0; }
boot_prep_linux函数跟内核传递参数有关系,为内核设置启动参数,u-boot向内核传递参数就是在这里做的准备:
boot_jump_linux会将tags的开始地址也就是gd->bd->bi_boot_params传给内核,并跳转到内核地址、启动内核,让内核解析这些tags。
1.2 boot_jump_linux
/* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images, int flag) { unsigned long machid = gd->bd->bi_arch_number; // 获取机器码 char *s; void (*kernel_entry)(int zero, int arch, uint params); // 内核入口函数 unsigned long r2; int fake = (flag & BOOTM_STATE_OS_FAKE_GO); kernel_entry = (void (*)(int, int, uint))images->ep; // 指定为内核入口地址 s = getenv("machid"); if (s) { if (strict_strtoul(s, 16, &machid) < 0) { debug("strict_strtoul failed!\n"); return; } printf("Using machid 0x%lx from environment\n", machid); } debug("## Transferring control to Linux (at address %08lx)" \ "...\n", (ulong) kernel_entry); bootstage_mark(BOOTSTAGE_ID_RUN_OS); announce_and_cleanup(fake); if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) // 如果使能FDT,并且扁平设备树长度大于0 r2 = (unsigned long)images->ft_addr; else r2 = gd->bd->bi_boot_params; if (!fake) { kernel_entry(0, machid, r2); } }
1.2.1 matchid
在之前内核移植的博客中,由于我们没有使用设备树,而是通过uboo传递一个machid给linux 内核(uboot在不设置machid环境变量时,uboot会使用默认的机器id),我们在Mini2440之linux内核移植中将其修改为了168:
#define MACH_TYPE_SMDK2440 168 // 新增的
内核启动的时候会根据machid来比较内核machine_desc中的.nr,machine_desc定义在内核arch/arm/mach-s3c24xx/mach-smdk2440.c文件:
MACHINE_START(S3C2440, "SMDK2440") /* Maintainer: Ben Dooks <ben-linux@fluff.org> */ .atag_offset = 0x100, .init_irq = s3c2440_init_irq, .map_io = smdk2440_map_io, .init_machine = smdk2440_machine_init, .init_time = smdk2440_init_time, MACHINE_END
宏MACHINE_START定义在arch/arm/include/asm/mach/arch.h,如下:
/* * Set of macros to define architecture features. This is built into * a table by the linker. */ #define MACHINE_START(_type,_name) \ static const struct machine_desc __mach_desc_##_type \ __used \ __attribute__((__section__(".arch.info.init"))) = { \ .nr = MACH_TYPE_##_type, \ .name = _name, #define MACHINE_END \ };
这里attribute((section(“.arch.info.init”)))就是利用了编译器的特性,把machine_desc放到了.arch.info.init段。
.init.arch.info : { __arch_info_begin = .; *(.arch.info.init) __arch_info_end = .; }
回到前面的MACHINE_START(_type,_name)宏,_type是S3C2440。经过##连接.nr = MACH_TYPE_##_type就变为:.nr = MACH_TYPE_S3C2440。
MACH_TYPE_S3C2440定义在arch/arm/include/generated/asm/mach-types.h:
#define MACH_TYPE_S3C2440 168
现在使用设备树的话,这个参数就不需要设置了。
1.2.2 r2
如果我们使用了设备树,r2将会被设备为dtb文件的开始地址:
r2 = (unsigned long)images->ft_addr;
否则r2为tags的开始地址。
二、linux内核设备树移植
为了学习设备树相关内容,这里我们重新克隆一个linux 5.2.8源码,然后在Mini2440之linux内核移植的基础上,介绍设备树移植相关的内容。
2.1 内核源码下载
我们这里下载linuxz-5.2.8版本,虚拟机ubuntu系统运行:
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.2.8.tar.gz
将源码解压:
tar -zvxf linux-5.2.8.tar.gz mv linux-5.2.8 linux-5.2.8-dt mv linux-5.2.8-dt /work/sambashare/ cd /work/sambashare/linux-5.2.8-dt/
2.2 配置Makefile
修改顶层的 Makefile,打开 Makefile 文件,找到下面语句:
ARCH ?= $(SUBARCH)
修改为:
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
其中,ARCH 是指定目标平台为arm,CROSS_COMPILE是指定交叉编译器,这里指定的 是系统默认的交叉编译器,如要使用其它的,则要把编译器的全路径在这里写出。
2.3 内核s3c2440_defconfig配置
接下来要做的就是内核配置、编译了。单板的默认配置文件在arch/arm/configs 目录下,如果没有2440相关的默认配置,可以选择比较相近的2410的配置修改。
root@zhengyang:/work/sambashare/linux-5.2.8-dt# ls arch/arm/configs | grep 24 mini2440_defconfig s3c2410_defconfig
虽然该目录下有Mini2440开发板相关的配置,但是本着学习的原则,并没有选择mini2440_defconfig;这里我直接选择s3c2410_defconfig。
配置文件s3c2410_defconfig支持很多单板,包括2440、2410,其定义如下:

CONFIG_SYSVIPC=y CONFIG_IKCONFIG=m CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_PARTITION_ADVANCED=y CONFIG_BSD_DISKLABEL=y CONFIG_SOLARIS_X86_PARTITION=y CONFIG_ARCH_S3C24XX=y CONFIG_CPU_S3C2412=y CONFIG_CPU_S3C2416=y CONFIG_CPU_S3C2440=y CONFIG_CPU_S3C2442=y CONFIG_CPU_S3C2443=y CONFIG_MACH_AML_M5900=y CONFIG_ARCH_BAST=y CONFIG_ARCH_H1940=y CONFIG_MACH_N30=y CONFIG_MACH_OTOM=y CONFIG_MACH_QT2410=y CONFIG_ARCH_SMDK2410=y CONFIG_MACH_TCT_HAMMER=y CONFIG_MACH_VR1000=y CONFIG_MACH_JIVE=y CONFIG_MACH_SMDK2412=y CONFIG_MACH_VSTMS=y CONFIG_MACH_SMDK2416=y CONFIG_MACH_ANUBIS=y CONFIG_MACH_AT2440EVB=y CONFIG_MACH_MINI2440=y CONFIG_MACH_NEXCODER_2440=y CONFIG_MACH_OSIRIS=y CONFIG_MACH_OSIRIS_DVS=m CONFIG_MACH_RX3715=y CONFIG_ARCH_S3C2440=y # 会链接mach-smdk2440.o CONFIG_MACH_NEO1973_GTA02=y CONFIG_MACH_RX1950=y CONFIG_MACH_SMDK2443=y CONFIG_S3C_ADC=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" CONFIG_FPE_NWFPE=y CONFIG_FPE_NWFPE_XP=y CONFIG_APM_EMULATION=m CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=m CONFIG_NET_KEY=m CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_NET_IPIP=m CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m CONFIG_TCP_CONG_ADVANCED=y CONFIG_TCP_CONG_HSTCP=m CONFIG_TCP_CONG_HYBLA=m CONFIG_TCP_CONG_SCALABLE=m CONFIG_TCP_CONG_LP=m CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_ILLINOIS=m CONFIG_IPV6_ROUTER_PREF=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m CONFIG_IPV6_MIP6=m CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_NETBIOS_NS=m CONFIG_NF_CONNTRACK_PPTP=m CONFIG_NF_CONNTRACK_SANE=m CONFIG_NF_CONNTRACK_SIP=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_CONNMARK=m CONFIG_NETFILTER_XT_TARGET_LED=m CONFIG_NETFILTER_XT_TARGET_LOG=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_CLUSTER=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_DCCP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_OWNER=m CONFIG_NETFILTER_XT_MATCH_POLICY=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_RATEEST=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_RECENT=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_IP_VS=m CONFIG_NF_CONNTRACK_IPV4=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_TTL=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_TARGET_NETMAP=m CONFIG_IP_NF_TARGET_REDIRECT=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m CONFIG_IP_NF_RAW=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_NF_CONNTRACK_IPV6=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m CONFIG_IP6_NF_MATCH_FRAG=m CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_MH=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m CONFIG_BT=m CONFIG_BT_RFCOMM=m CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_BNEP=m CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_BCSP=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m CONFIG_BT_HCIVHCI=m CONFIG_CFG80211=m CONFIG_MAC80211=m CONFIG_MAC80211_MESH=y CONFIG_MAC80211_LEDS=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_ROM=y CONFIG_MTD_RAW_NAND=y CONFIG_MTD_NAND_S3C2410=y CONFIG_PARPORT=y CONFIG_PARPORT_PC=m CONFIG_PARPORT_AX88796=m CONFIG_PARPORT_1284=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_ATA_OVER_ETH=m CONFIG_EEPROM_AT24=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ATA=y CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_DM9000=y CONFIG_INPUT_EVDEV=y CONFIG_MOUSE_APPLETOUCH=m CONFIG_MOUSE_BCM5974=m CONFIG_INPUT_JOYSTICK=y CONFIG_JOYSTICK_ANALOG=m CONFIG_JOYSTICK_A3D=m CONFIG_JOYSTICK_ADI=m CONFIG_JOYSTICK_COBRA=m CONFIG_JOYSTICK_GF2K=m CONFIG_JOYSTICK_GRIP=m CONFIG_JOYSTICK_GRIP_MP=m CONFIG_JOYSTICK_GUILLEMOT=m CONFIG_JOYSTICK_INTERACT=m CONFIG_JOYSTICK_SIDEWINDER=m CONFIG_JOYSTICK_TMDC=m CONFIG_JOYSTICK_IFORCE=m CONFIG_JOYSTICK_MAGELLAN=m CONFIG_JOYSTICK_SPACEORB=m CONFIG_JOYSTICK_SPACEBALL=m CONFIG_JOYSTICK_STINGER=m CONFIG_JOYSTICK_TWIDJOY=m CONFIG_JOYSTICK_ZHENHUA=m CONFIG_JOYSTICK_DB9=m CONFIG_JOYSTICK_GAMECON=m CONFIG_JOYSTICK_TURBOGRAFX=m CONFIG_JOYSTICK_JOYDUMP=m CONFIG_JOYSTICK_XPAD=m CONFIG_JOYSTICK_XPAD_FF=y CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=m CONFIG_INPUT_MISC=y CONFIG_INPUT_ATI_REMOTE2=m CONFIG_INPUT_KEYSPAN_REMOTE=m CONFIG_INPUT_POWERMATE=m CONFIG_INPUT_YEALINK=m CONFIG_INPUT_CM109=m CONFIG_INPUT_UINPUT=m CONFIG_INPUT_GPIO_ROTARY_ENCODER=m CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_SAMSUNG=y CONFIG_SERIAL_SAMSUNG_CONSOLE=y CONFIG_SERIAL_DEV_BUS=m CONFIG_PRINTER=y CONFIG_PPDEV=y CONFIG_HW_RANDOM=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_S3C2410=y CONFIG_I2C_SIMTEC=y CONFIG_SPI=y CONFIG_SPI_GPIO=m CONFIG_SPI_S3C24XX=m CONFIG_SPI_SPIDEV=m CONFIG_SPI_TLE62X0=m CONFIG_SENSORS_LM75=m CONFIG_SENSORS_LM78=m CONFIG_SENSORS_LM85=m CONFIG_WATCHDOG=y CONFIG_S3C2410_WATCHDOG=y CONFIG_MFD_SM501=y CONFIG_TPS65010=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_S3C2410=y CONFIG_FB_SM501=y CONFIG_BACKLIGHT_PWM=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SEQUENCER=m CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_VERBOSE_PRINTK=y # CONFIG_SND_DRIVERS is not set # CONFIG_SND_ARM is not set # CONFIG_SND_SPI is not set CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_CAIAQ=m CONFIG_SND_SOC=y # CONFIG_USB_HID is not set CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m CONFIG_USB_WDM=m CONFIG_USB_STORAGE=m CONFIG_USB_STORAGE_DATAFAB=m CONFIG_USB_STORAGE_FREECOM=m CONFIG_USB_STORAGE_ISD200=m CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STORAGE_SDDR09=m CONFIG_USB_STORAGE_SDDR55=m CONFIG_USB_STORAGE_JUMPSHOT=m CONFIG_USB_STORAGE_ALAUDA=m CONFIG_USB_STORAGE_ONETOUCH=m CONFIG_USB_STORAGE_KARMA=m CONFIG_USB_STORAGE_CYPRESS_ATACB=m CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m CONFIG_USB_USS720=m CONFIG_USB_SERIAL=y CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_FTDI_SIO=y CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=y CONFIG_USB_SERIAL_OPTION=m CONFIG_USB_EMI62=m CONFIG_USB_EMI26=m CONFIG_USB_ADUTUX=m CONFIG_USB_SEVSEG=m CONFIG_USB_RIO500=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m CONFIG_USB_CYPRESS_CY7C63=m CONFIG_USB_CYTHERM=m CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m CONFIG_USB_LD=m CONFIG_USB_TRANCEVIBRATOR=m CONFIG_USB_IOWARRIOR=m CONFIG_USB_TEST=m CONFIG_MMC=y CONFIG_SDIO_UART=m CONFIG_MMC_TEST=m CONFIG_MMC_SDHCI=m CONFIG_MMC_SPI=m CONFIG_MMC_S3C=y CONFIG_LEDS_S3C24XX=m CONFIG_LEDS_PCA9532=m CONFIG_LEDS_GPIO=m CONFIG_LEDS_PCA955X=m CONFIG_LEDS_DAC124S085=m CONFIG_LEDS_PWM=m CONFIG_LEDS_BD2802=m CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_LEDS_TRIGGER_GPIO=m CONFIG_LEDS_TRIGGER_DEFAULT_ON=m CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_S3C=y CONFIG_DMADEVICES=y CONFIG_S3C24XX_DMAC=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_UDF_FS=m CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_NTFS_FS=m CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_CONFIGFS_FS=m CONFIG_JFFS2_FS=y CONFIG_JFFS2_SUMMARY=y CONFIG_CRAMFS=y CONFIG_SQUASHFS=m CONFIG_ROMFS_FS=y CONFIG_NFS_FS=y CONFIG_NFS_V3_ACL=y CONFIG_ROOT_NFS=y CONFIG_NFSD=m CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_CIFS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=m CONFIG_NLS_CODEPAGE_775=m CONFIG_NLS_CODEPAGE_850=y CONFIG_NLS_CODEPAGE_852=m CONFIG_NLS_CODEPAGE_855=m CONFIG_NLS_CODEPAGE_857=m CONFIG_NLS_CODEPAGE_860=m CONFIG_NLS_CODEPAGE_861=m CONFIG_NLS_CODEPAGE_862=m CONFIG_NLS_CODEPAGE_863=m CONFIG_NLS_CODEPAGE_864=m CONFIG_NLS_CODEPAGE_865=m CONFIG_NLS_CODEPAGE_866=m CONFIG_NLS_CODEPAGE_869=m CONFIG_NLS_CODEPAGE_936=m CONFIG_NLS_CODEPAGE_950=m CONFIG_NLS_CODEPAGE_932=m CONFIG_NLS_CODEPAGE_949=m CONFIG_NLS_CODEPAGE_874=m CONFIG_NLS_ISO8859_8=m CONFIG_NLS_CODEPAGE_1250=m CONFIG_NLS_CODEPAGE_1251=m CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_2=m CONFIG_NLS_ISO8859_3=m CONFIG_NLS_ISO8859_4=m CONFIG_NLS_ISO8859_5=m CONFIG_NLS_ISO8859_6=m CONFIG_NLS_ISO8859_7=m CONFIG_NLS_ISO8859_9=m CONFIG_NLS_ISO8859_13=m CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m CONFIG_DEBUG_INFO=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_USER=y CONFIG_DEBUG_LL=y
然后复制一份,得到s3c2440_defconfig:
cp arch/arm/configs/s3c2410_defconfig arch/arm/configs/s3c2440_defconfig
在linux内核根目录下执行如下命令,执行完之后会在内核根目录下生成默认配置文件.config:
root@zhengyang:/work/sambashare/linux-5.2.8-dt# make s3c2440_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 # # configuration written to .config #
2.4 设备树配置
在linux内核中,既然要使用设备树,我们先看内核中是否已有支持S3C2440的设备树文件。进入linux内核源代码目录,内核根路径下运行命令:
root@zhengyang:/work/sambashare/linux-5.2.8-dt# ls arch/arm/boot/dts | grep s3c s3c2416.dtsi s3c2416-pinctrl.dtsi s3c2416-smdk2416.dts s3c24xx.dtsi s3c6400.dtsi s3c6410.dtsi s3c6410-mini6410.dts s3c6410-smdk6410.dts s3c64xx.dtsi s3c64xx-pinctrl.dtsi
s3c24xx.dtsi 中存放的是s3c24xx系列SoC公共的一些属性,如中断控制器、串口、看门狗、RTC、I2C控制器等等,具体如下:

// SPDX-License-Identifier: GPL-2.0 /* * Samsung's S3C24XX family device tree source * * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de> */ / { compatible = "samsung,s3c24xx"; interrupt-parent = <&intc>; #address-cells = <1>; #size-cells = <1>; aliases { pinctrl0 = &pinctrl_0; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; }; intc:interrupt-controller@4a000000 { compatible = "samsung,s3c2410-irq"; reg = <0x4a000000 0x100>; interrupt-controller; #interrupt-cells = <4>; }; pinctrl_0: pinctrl@56000000 { reg = <0x56000000 0x1000>; wakeup-interrupt-controller { compatible = "samsung,s3c2410-wakeup-eint"; interrupts = <0 0 0 3>, <0 0 1 3>, <0 0 2 3>, <0 0 3 3>, <0 0 4 4>, <0 0 5 4>; }; }; timer@51000000 { compatible = "samsung,s3c2410-pwm"; reg = <0x51000000 0x1000>; interrupts = <0 0 10 3>, <0 0 11 3>, <0 0 12 3>, <0 0 13 3>, <0 0 14 3>; #pwm-cells = <4>; }; uart0: serial@50000000 { compatible = "samsung,s3c2410-uart"; reg = <0x50000000 0x4000>; interrupts = <1 28 0 4>, <1 28 1 4>; status = "disabled"; }; uart1: serial@50004000 { compatible = "samsung,s3c2410-uart"; reg = <0x50004000 0x4000>; interrupts = <1 23 3 4>, <1 23 4 4>; status = "disabled"; }; uart2: serial@50008000 { compatible = "samsung,s3c2410-uart"; reg = <0x50008000 0x4000>; interrupts = <1 15 6 4>, <1 15 7 4>; status = "disabled"; }; watchdog@53000000 { compatible = "samsung,s3c2410-wdt"; reg = <0x53000000 0x100>; interrupts = <0 0 9 3>; status = "disabled"; }; rtc@57000000 { compatible = "samsung,s3c2410-rtc"; reg = <0x57000000 0x100>; interrupts = <0 0 30 3>, <0 0 8 3>; status = "disabled"; }; i2c@54000000 { compatible = "samsung,s3c2410-i2c"; reg = <0x54000000 0x100>; interrupts = <0 0 27 3>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; };
此外,并没有支持2440的设备树,最接近的只有2416的设备树。
2.4.1 添加设备树
仿照s3c2416-smdk2416.dts的结构添加了Mini2440的设备树需要的文件。执行如下命令:
root@zhengyang:/work/sambashare/linux-5.2.8-dt# cd arch/arm/boot/dts root@zhengyang:/work/sambashare/linux-5.2.8-dt/arch/arm/boot/dts# cp s3c2416.dtsi s3c2440.dtsi root@zhengyang:/work/sambashare/linux-5.2.8-dt/arch/arm/boot/dts# cp s3c2416-pinctrl.dtsi s3c2440-pinctrl.dtsi root@zhengyang:/work/sambashare/linux-5.2.8-dt/arch/arm/boot/dts# cp s3c2416-smdk2416.dts s3c2440-smdk2440.dts
代码含义:
- 复制s3c2416.dtsi为s3c2440.dtsi;
- 复制s3c2416-pinctrl.dtsi为s3c2440-pinctrl.dtsi;
- 复制s3c2416-smdk2416.dts为s3c2440-smdk2440.dts;
下面是设备树的结构:
s3c2440-smdk2440.dts ----> s3c2440.dtsi ----> s3c24xx.dtsi ----> skeleton.dtsi ----> s3c2440-pinctrl.dtsi
大概介绍一下上面各个文件:
- s3c2440.dtsi存放的是s3c2440这个SoC跟其他s3c24xx系列不同的一些硬件信息,如clock控制器、串口等等;
- s3c2440-pinctrl.dtsi存放的是s3c2440这个SoC中GPIO控制器、外部中断控制器、引脚复用等信息的配置;
- s3c2440-smdk2440.dts存放的是Mini2440的硬件信息;
- skeleton.dtsi 存放的是一个设备树必备的一些基本属性;
这些文件之前是有包含关系的,设备树这样一层层包含的好处是:在同名节点中,后出现的属性会覆盖前面出现的同名属性,不同的属性将来会合并到所隶属的同名的节点下面。
2.4.2 修改设备树Makefile
先修改设备树的Makefile:
root@zhengyang:/work/sambashare/linux-5.2.8-dt/arch/arm/boot/dts# vim Makefile
新增s3c2440-smdk2440.dtb:
dtb-$(CONFIG_ARCH_S3C24XX) += \ s3c2416-smdk2416.dtb \ s3c2440-smdk2440.dtb
由于CONFIG_ARCH_S3C24XX在arch/arm/configs/s3c2440_defconfig文件中定义,这样make dtbs的时候就会编译s3c2440-smdk2440.dtb。
2.5 支持Mini2440开发板
修改Makefile和Kconfig,并添加Mini2440的板子信息,使内核在启动时能从设备树文件中解析到的信息匹配到Mini2440板子。
2.5.1 修改arch/arm/mach-s3c24xx/Kconfig
添加ARCH_S3C2440_DT信息:
config ARCH_S3C2440 bool "SMDK2440" select S3C2440_XTAL_16934400 select S3C24XX_SMDK select S3C_DEV_NAND select S3C_DEV_USB_HOST help Say Y here if you are using the SMDK2440. config SMDK2440_CPU2440 bool "SMDK2440 with S3C2440 CPU module" default y if ARCH_S3C2440 select S3C2440_XTAL_16934400 config ARCH_S3C2440_DT bool "MINI2440 using devicetree" select TIMER_OF select USE_OF select PINCTRL select PINCTRL_S3C24XX help Say Y here if you are using the MINI2440 with device tree enabled.
这样的话,在make menuconfig的時候,选择ARCH_S3C2440_DT这个配置。选择了这个配置,CONFIG_TIMER_OF、CONFIG_USE_OF、CONFIG_PINCTRL、CONFIG_S3C24XX都会被配置上。
2.5.2 修改arch/arm/mach-s3c24xx/Makefile
obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o obj-$(CONFIG_MACH_S3C2416_DT) += mach-s3c2416-dt.o obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o obj-$(CONFIG_ARCH_S3C2440_DT) += mach-smdk2440-dt.o # 新增
在menuconfig上选择了ARCH_S3C2440_DT后, 在make uImage的时候会定义CONFIG_ARCH_S3C2440_DT宏,这样就会编译链接mach-smdk2440-dt.c。
2.5.3 新增arch/arm/mach-s3c24xx/mach-smdk2440-dt.c
mach-smdk2440-dt.c文件内容参考mach-s3c2416-dt.c:
#include <linux/clocksource.h> #include <linux/irqchip.h> #include <linux/serial_s3c.h> #include <asm/mach/arch.h> #include <mach/map.h> #include <plat/cpu.h> #include <plat/pm.h> #include "common.h" static void __init s3c2440_dt_map_io(void) { s3c24xx_init_io(NULL, 0); } static void __init s3c2440_dt_machine_init(void) { s3c_pm_init(); } static const char *const s3c2440_dt_compat[] __initconst = { "samsung,s3c2440", "samsung,mini2440", NULL }; DT_MACHINE_START(S3C2440_DT, "Samsung S3C2440 (Flattened Device Tree)") /* Maintainer: Heiko Stuebner <heiko@sntech.de> */ .dt_compat = s3c2440_dt_compat, .map_io = s3c2440_dt_map_io, .init_irq = irqchip_init, .init_machine = s3c2440_dt_machine_init, MACHINE_END
这里我们需要注意的是dt_compat数组,其中的值要跟设备树中的compatible匹配,后面会介绍arch/arm/boot/dts/s3c2440-smdk2440-dt.dts的配置。
2.6 内核裁切
由于我们默认配置编译生成的内核文件是比较大,大概有3.5M的样子,这其中我们编译了许多无用的配置。因此需要对内核进行裁切。
然后可以通过make menuconfig修改配置:
make menuconfig
2.6.1 支持设备树
配置内核支持设备树,实际上linux 5.2.8已经默认支持设备树了:那么内核在启动时,不会通过uboot传入的machid来找到单板文件;而是通过上面的dt_compat数组中的信息和设备树中的compatible进行匹配,以此来找到相应单板文件;
Boot options ---> -*- Flattened Device Tree support
2.6.2 单板裁切
比如,默认编译的的内核,支持了多种单板。配置内核支持Mini2440单板文件,如下图所示,SoC下只选择S3C2440,单板文件下只选择MINI2440 using devicetree:
2.6.3 支持DM9000网卡
配置内核支持DM9000网卡:linux驱动移植-DM9000网卡驱动;
Device Drivers ---> [*] Network device support ---> [*] Ethernet driver support ---> <*> DM9000 support
即可找到DM9000的配置项,可以看到DM9000已经被选中,这是因为linux-5.2.8 默认的内核配置已经加入了DM9000的支持:
2.6.4 支持NFS文件系统
使用NFS作为根文件系统,因为文件系统在宿主机中,这样在修改文件系统就非常方便,主要用于开发阶段使用。
File systems ---> [*] Network File Systems ---> <*> NFS client support for NFS version 4
勾选NFS client support for NFS version 4。
2.6.5 支持内核调试日志
配置打开内核调试,为了能够尽量看到更多内核启动早期的log,一定要在内核配置文件中把内核早期的log配置打开:
Kernel hacking ---> [*] Kernel low-level debugging functions (read help!) Kernel low-level debugging port (Use Samsung S3C UART 0 for low-level debug) ---> [*] Early printk
这里串口选择启动参数bootargs中控制台指定的串口。
除了上面的配置,还必须在bootargs中添加一个earlyprintk字符串,否则这些log还是打印不出来。此外,建议再在bootargs中添加一个ignore_loglevel参数,防止有些模块的log由于loglevel的问题无法输出log。
2.6.6 配置EABI编译属性
因为arm-none-linux-gnueabi 4.8.3使用了EABI方式,所以这就需要内核同样配置EABI编译属性:
Kernel Features ---> [*] Use the ARM EABI to compile the kernel [*] Allow old ABI binaries to run with this kernel (EXPERIMENTAL)
2.6.7 配置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下无法生成节点的分析思路和解决方法及原理。
2.6.8 保存配置
保存配置:
存档:
mv s3c2440_defconfig ./arch/arm/configs/
重新配置内核:
root@zhengyang:/work/sambashare/linux-5.2.8-dt# make s3c2440_defconfig
2.7 编译内核
2.7.1 编译内核
在linux内核根目录下执行如下命令:
make V=1 uImage
uImage内核内核是通过如下命令得到的:
root@zhengyang:/work/sambashare/linux-5.2.8-dt# cat arch/arm/boot/.uImage.cmd cmd_arch/arm/boot/uImage := /bin/bash ./scripts/mkuboot.sh -A arm -O linux -C none -T kernel -a 0x30008000 -e 0x30008000 -n 'Linux-5.2.8' -d arch/arm/boot/zImage arch/arm/boot/uImage
其中:
亲爱的读者和支持者们,自动博客加入了打赏功能,陆陆续续收到了各位老铁的打赏。在此,我想由衷地感谢每一位对我们博客的支持和打赏。你们的慷慨与支持,是我们前行的动力与源泉。
日期 | 姓名 | 金额 |
---|---|---|
2023-09-06 | *源 | 19 |
2023-09-11 | *朝科 | 88 |
2023-09-21 | *号 | 5 |
2023-09-16 | *真 | 60 |
2023-10-26 | *通 | 9.9 |
2023-11-04 | *慎 | 0.66 |
2023-11-24 | *恩 | 0.01 |
2023-12-30 | I*B | 1 |
2024-01-28 | *兴 | 20 |
2024-02-01 | QYing | 20 |
2024-02-11 | *督 | 6 |
2024-02-18 | 一*x | 1 |
2024-02-20 | c*l | 18.88 |
2024-01-01 | *I | 5 |
2024-04-08 | *程 | 150 |
2024-04-18 | *超 | 20 |
2024-04-26 | .*V | 30 |
2024-05-08 | D*W | 5 |
2024-05-29 | *辉 | 20 |
2024-05-30 | *雄 | 10 |
2024-06-08 | *: | 10 |
2024-06-23 | 小狮子 | 666 |
2024-06-28 | *s | 6.66 |
2024-06-29 | *炼 | 1 |
2024-06-30 | *! | 1 |
2024-07-08 | *方 | 20 |
2024-07-18 | A*1 | 6.66 |
2024-07-31 | *北 | 12 |
2024-08-13 | *基 | 1 |
2024-08-23 | n*s | 2 |
2024-09-02 | *源 | 50 |
2024-09-04 | *J | 2 |
2024-09-06 | *强 | 8.8 |
2024-09-09 | *波 | 1 |
2024-09-10 | *口 | 1 |
2024-09-10 | *波 | 1 |
2024-09-12 | *波 | 10 |
2024-09-18 | *明 | 1.68 |
2024-09-26 | B*h | 10 |
2024-09-30 | 岁 | 10 |
2024-10-02 | M*i | 1 |
2024-10-14 | *朋 | 10 |
2024-10-22 | *海 | 10 |
2024-10-23 | *南 | 10 |
2024-10-26 | *节 | 6.66 |
2024-10-27 | *o | 5 |
2024-10-28 | W*F | 6.66 |
2024-10-29 | R*n | 6.66 |
2024-11-02 | *球 | 6 |
2024-11-021 | *鑫 | 6.66 |
2024-11-25 | *沙 | 5 |
2024-11-29 | C*n | 2.88 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2019-04-02 Java基础 -- 持有对象(容器)
2018-04-02 第三节,TensorFlow 使用CNN实现手写数字识别(卷积函数tf.nn.convd介绍)
2018-04-02 数据处中模块之matplotlib