----------------------------------------------------------------------------------------------------------------------------
内核版本: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 environmentn", 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
View Code

然后复制一份,得到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";
        };
};
View Code

此外,并没有支持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

其中:

  • -a : 设置内核镜像加载地址;zImage解压之后得到Image会加载到这个地址上;
  • -e :设置内核镜像入口地址;内核启动的入口地址;

将uImage复制到tftp服务器路径下:

root@zhengyang:/work/sambashare/linux-5.2.8-dt# cp /work/sambashare/linux-5.2.8-dt/arch/arm/boot/uImage /work/tftpboot/
2.7.2 编译dts

在linux内核根目录执行如下命令:

root@zhengyang:/work/sambashare/linux-5.2.8-dt# make dtbs
  DTC     arch/arm/boot/dts/s3c2416-smdk2416.dtb
  DTC     arch/arm/boot/dts/s3c2440-smdk2440.dtb

编译设备树文件,把前面配置过的arch/arm/boot/dts里的dts文件编译成dtb文件。

将s3c2440-smdk2440.dtb复制到tftp服务器路径下:

root@zhengyang:/work/sambashare/linux-5.2.8-dt# cp /work/sambashare/linux-5.2.8-dt/arch/arm/boot/dts/s3c2440-smdk2440.dtb /work/tftpboot/

三、uboot支持FDT

关于Mini2440 uboot移植我们之前已经介绍过了,因此就不重新介绍了。具体参考Young / s3c2440_project[u-boot-2016.05-linux]。

3.1 支持FDT(扁平设备树)

我们如何修改uboot使其支持FDT呢,我们需要在uboot源码configs/smdk2440_defconfig文件中配置(或者通过make menuconfig进行配置):

CONFIG_OF_LIBFDT=y

配置CONFIG_OF_LIBFDT之后,uboot编译时将会链接lib/libfdt文件夹下文件:

lib/Makefile:54:obj-$(CONFIG_OF_LIBFDT) += libfdt/
3.1.1 编译uboot
make distclean
make smdk2440_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux- V=1

需要注意的是,如果编译得到的u-boot.bin文件大于256KB,无法通过MiniTools工具下载的,因此需要进行裁切,使其小于256KB。比如配置include/configs/smdk2440.h :

/* support additional compression methods */
#if 0
#define CONFIG_BZIP2
#define CONFIG_LZO
#define CONFIG_LZMA
#endif
3.1.2 下载uboot

使用MiniTools下载uboot程序到NAND FLASH。

3.2 启动内核

开发板uboot启动完成后,内核启动前,按下任意键,进入uboot。uboot启动后,需要设置启动参数:

set bootargs "noinitrd console=ttySAC0,115200 root=/dev/nfs rw nfsroot=192.168.0.200:/work/nfs_root/rootfs ip=192.168.0.105:192.168.0.200:192.168.0.1:255.255.255.0::eth0:off ignore_loglevel earlyprintk"
save

这里我们通过bootargs告知内核根文件系统为NFS网络文件系统,并详细的设置了ip,服务器ip,网关等网络参数信息,方便内核启动时直接通过这些参数去挂载NFS网络文件系统。关于根文件系统制作参考:Mini2440之linux内核移植之yaffs2根文件系统移植

uboot支持FDT后,我们便可以将dtb下载到内存地址0x30001000中:

SMDK2440 # tftp 0x30001000 s3c2440-smdk2440.dtb

然后将内核镜像加载到内存0x30008000地址,并烧录内核到NAND FLASH:

SMDK2440 # tftp 30008000 uImage
SMDK2440 # nand erase.part kernel
SMDK2440 # nand write 30008000 kernel

然后可以使用如下命令启动内核:

SMDK2440 # bootm 0x30008000 - 0x30001000   // 无设备树时,直接bootm 0x30008000
//bootm  uImage地址  ramdisk地址  设备树镜像地址

其中:

  • 第一个参数为内核映像在内存的地址;
  • 第二个参数为initrd的地址,若不存在initrd,可以用“-”符号代替;
  • 第三个参数dtb_address为.dtb文件在内存的地址;

此外对于dtb的地址0x30000000,我们需要遵循以下原则:

  • 不要破坏uboot本身;
  • 不要破坏内核本身: 内核本身的空间不能占用, 内核要用到的内存区域也不能占用;

由于Mini2440的内存区间为0x30000000~0x34000000,并且:

  • 高地位为uboot,以及uboot使用的栈空间;
  • 这里我们将内核加载地址修改为0x30008000地址,内核启动时一般会在它所处位置的下边放置页表,这块空间(一般是0x4000即16K字节)不能被占用;

3.3  开发板测试

开发板运行上电运行后,结果如下:

U-Boot 2016.05 (Apr 11 2023 - 22:47:36 +0800)

CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
UCLK:       48 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 0 Bytes
NAND:  128 MiB
In:    serial
Out:   serial
Err:   serial
Net:   dm9000
Hit any key to stop autoboot:  0
SMDK2440 # tftp 0x30001000 s3c2440-smdk2440.dtb
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
operating at unknown: 0 mode
Using dm9000 device
TFTP from server 192.168.0.200; our IP address is 192.168.0.188
Filename 's3c2440-smdk2440.dtb'.
Load address: 0x30001000
Loading: #
         1000 Bytes/s
done
Bytes transferred = 5851 (16db hex)
SMDK2440 # tftp 30008000 uImage
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:5b
operating at unknown: 0 mode
Using dm9000 device
TFTP from server 192.168.0.200; our IP address is 192.168.0.188
Filename 'uImage'.
Load address: 0x30008000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         ######
         1.1 MiB/s
done
Bytes transferred = 3896232 (3b73a8 hex)
SMDK2440 # bootm 0x30008000 - 0x30001000
## Booting kernel from Legacy Image at 30008000 ...
   Image Name:   Linux-5.2.8
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3896168 Bytes = 3.7 MiB
   Load Address: 30008000
   Entry Point:  30008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
Using machid 0xa8 from environment

Starting kernel ...

结果发现,内核和设备树加载到内存后,内核无法正常运行;后续就是设备树的修改工作了。

如果修改设备树中的设备节点信息,有两种办法;

  • 修改dts文件,重新编译得到dtb并上传烧写
  • 使用uboot提供的一些命令来修改dtb文件,修改后再把它保存到板子上;

关于设备树修改我们在下一节单独介绍。

参考文章

[1]linux设备驱动(19)设备树详解3-u-boot传输dts

[2]linux设备驱动(20)设备树详解4-kernel解析dts

[3]linux设备驱动(21)设备树详解5-dts的应用

[4]第四课:u-boot对设备树的支持

[5][uboot] (番外篇)uboot之fdt介绍

[6]内核解析U-boot传入的machid

[7]在JZ2440上移植设备树---下:内核和设备树移植

[8]讓TQ2440也用上設備樹(1) 

[9]TQ2440设备树

[10]Exynos4412的Linux5.4.174时钟驱动开发(五)——时钟设备树的修改方法

[11]在linux4.15 移植设备树到JZ2440

[12]https://www.kernelconfig.io/(内核配置项)

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/zyly/p/17274776.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程