开发环境:win7 64位 +  Ubuntu16.04 64位

开发板:tiny4412ADK + S700 + 4GB eMMC + 1G DDR3

工具链:友善之臂提供的 arm-linux-gnueabihf-  (gcc version 6.3.0)  //低版本的工具编译不了最新的uboot

要移植的u-boot版本:u-boot-2019-01

git仓库地址:https://github.com/songchong11/tiny4412-uboot-2019.git

1.移植

采用最新的uboot-2019-01,它其实对exynos4412已经有了较好的支持。

在board/samsung下有很多版型可以给我们参考:origen、odroid、trats、trats2等。但是只有origen支持配置SPL,适合tiny4412,其他三个不适合tiny4412,以odroid为例,这个配置最后是编译出一个镜像u-boot-dtb.bin,没有spl,结合exynos4412的启动,即便把u-boot-dtb.bin的前14k强制裁出来作为BL2,在BL2代码中的board_init_f中调用的一些函数的相对地址(相对于spl的起始地址,即0x02023400)已经超过24KB,甚至超过16KB, 我们知道,BL2是在iRAM中运行,并且地址空间最多16KB,因此会导致问题。

下面开始移植:

修改顶层Makefile,指定编译器和芯片架构为ARM

diff --git a/Makefile b/Makefile
index 6aa0896..94906d1 100644
--- a/Makefile
+++ b/Makefile
@@ -243,7 +243,9 @@ export      HOSTARCH HOSTOSifeq ($(HOSTARCH),$(ARCH))CROSS_COMPILE ?=endif
-
+ARCH = arm
+CROSS_COMPILE = arm-linux-gnueabihf-KCONFIG_CONFIG ?= .configexport KCONFIG_CONFIG@@ -906,8 +908,8 @@ cmd_pad_cat = $(cmd_objcopy) && $(append) || rm -f $@cfg: u-boot.cfg

拷贝exynos441-origen.dts文件为exynos4412-tiny4412.dts,并修改Makefile

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index dda4e59..a71d08d 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -12,7 +12,8 @@ dtb-$(CONFIG_EXYNOS4) += exynos4210-origen.dtb \exynos4210-universal_c210.dtb \exynos4210-trats.dtb \exynos4412-trats2.dtb \
-       exynos4412-odroid.dtb
+       exynos4412-tiny4412.dtb

---------------------------------

新增exynos4412-tiny4412.dts并修改它

diff --git a/arch/arm/dts/exynos4412-tiny4412.dts b/arch/arm/dts/exynos4412-tiny4412.dts
new file mode 100755
index 0000000..898a6a5
--- /dev/null
+++ b/arch/arm/dts/exynos4412-tiny4412.dts
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Odroid-U3/X2 board device tree source
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ */
+
+/dts-v1/;
+#include "exynos4412.dtsi"
+
+/ {
+       model = "FriendlyARM TINY4412 board based on Exynos4412";
+       compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
+
+       chosen {
+               stdout-path = "serial0";
+               bootargs ="";
+       };
+       aliases {
+               serial0 = "/serial@13800000";
+               console = "/serial@13800000";
+               //mmc0 = &mshc_0;
+               //mmc1 = &sdhci2;
+               mmc0 = "/sdhci@12530000";
+               mmc1 = "/dwmmc@12550000";
+       };
+
+       serial0:serial@13810000 {
+               status = "okay";
+       };
+
+       ehci@12580000 {
+               compatible = "samsung,exynos-ehci";
+               reg = <0x12580000 0x100>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               phy {
+                       compatible = "samsung,exynos-usb-phy";
+                       reg = <0x125B0000 0x100>;
+               };
+       };
+       sdhci@12510000 {
+                compatible = "samsung,exynos4412-sdhci";
+                        status = "disabled";
+       };
+
+       sdhci@12520000 {
+                compatible = "samsung,exynos4412-sdhci";
+                status = "disabled";
+       };
+
+        sdhci@12530000 {
+                 compatible = "samsung,exynos4412-sdhci";
+                 samsung,bus-width = <4>;
+                  samsung,timing = <1 2 3>;
+                  cd-gpios = <&gpk2 2 0>;
+        };
+
+        sdhci@12540000 {
+                compatible = "samsung,exynos4412-sdhci";
+                status = "disabled";
+        };
+       dwmmc@12550000 {
+               samsung,bus-width = <8>;
+               samsung,timing = <2 1 0>;
+               samsung,removable = <0>;
+               fifoth_val = <0x203f0040>;
+               bus_hz = <400000000>;
+               div = <0x3>;
+               index = <4>;
+       };
+       emmc-reset {
+               compatible = "samsung,emmc-reset";
+               reset-gpio = <&gpk1 2 0>;
+       };
+};
+
+&sdhci2 {
+       samsung,bus-width = <4>;
+       samsung,timing = <1 2 3>;
+       cd-gpios = <&gpk2 2 0>;
+       status = "okay";
+};
+
+&mshc_0 {
+       samsung,bus-width = <8>;
+       samsung,timing = <2 1 0>;
+       samsung,removable = <0>;
+       fifoth_val = <0x203f0040>;
+       bus_hz = <400000000>;
+       div = <0x3>;
+       index = <4>;
+       status = "okay";
+};

增加tiny4412 machine ID

diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
index 9f82efe..e8caba0 100644
--- a/arch/arm/include/asm/mach-types.h
+++ b/arch/arm/include/asm/mach-types.h
@@ -3403,6 +3403,7 @@#define MACH_TYPE_MONCH                3453#define MACH_TYPE_CURACAO              3454#define MACH_TYPE_ORIGEN               3455
+#define MACH_TYPE_TINY4412             4608#define MACH_TYPE_EPC10                3456#define MACH_TYPE_SGH_I740             3457#define MACH_TYPE_TUNA                 3458

修改arch/arm/mach-exynos/Kconfig文件,在执行make menuconfig的时候能够看到我们的修改

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
old mode 100644
new mode 100755
index ed04369..1735381
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -59,6 +59,10 @@ config TARGET_S5PC210_UNIVERSALconfig TARGET_ORIGENbool "Exynos4412 Origen board"select SUPPORT_SPL
+
+config TARGET_TINY4412
+       bool "Exynos4412 Tiny4412 board"
+       select SUPPORT_SPLconfig TARGET_TRATS2bool "Exynos4412 Trat2 board"
@@ -156,6 +160,7 @@ source "board/samsung/smdkv310/Kconfig"source "board/samsung/trats/Kconfig"source "board/samsung/universal_c210/Kconfig"source "board/samsung/origen/Kconfig"
+source "board/samsung/tiny4412/Kconfig"source "board/samsung/trats2/Kconfig"source "board/samsung/odroid/Kconfig"source "board/samsung/arndale/Kconfig"

修改/arch/arm/mach-exynos/Makefile

diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index e895c13..8597e08 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -12,7 +12,10 @@ obj-$(CONFIG_EXYNOS5420)     += sec_boot.oifdef CONFIG_SPL_BUILDobj-$(CONFIG_EXYNOS5)  += clock_init_exynos5.oobj-$(CONFIG_EXYNOS5)  += dmc_common.o dmc_init_ddr3.o
-obj-$(CONFIG_EXYNOS4210)+= dmc_init_exynos4.o clock_init_exynos4.o
+#obj-$(CONFIG_EXYNOS4210)+= dmc_init_exynos4.o clock_init_exynos4.o
+ifneq (,$(filter y, $(CONFIG_EXYNOS4210)$(CONFIG_TINY4412)))
+obj-y  += dmc_init_exynos4.o clock_init_exynos4.oobj-y  += spl_boot.o tzpc.oobj-y  += lowlevel_init.oendif
+endif

修改时钟寄存器,初始化时钟

diff --git a/arch/arm/mach-exynos/clock_init_exynos4.c b/arch/arm/mach-exynos/clock_init_exynos4.c
old mode 100644
new mode 100755
index 584e4ba..fda1837
--- a/arch/arm/mach-exynos/clock_init_exynos4.c
+++ b/arch/arm/mach-exynos/clock_init_exynos4.c
@@ -38,42 +38,39 @@*/void system_clock_init(void){
-       struct exynos4_clock *clk =
-                       (struct exynos4_clock *)samsung_get_base_clock();
+       struct exynos4x12_clock *clk =
+                       (struct exynos4x12_clock *)samsung_get_base_clock();-       writel(CLK_SRC_CPU_VAL, &clk->src_cpu);
+       /* APLL= 1400 MHz MPLL=800 MHz */
+
+       writel(0x01000001, &clk->src_cpu);sdelay(0x10000);-       writel(CLK_SRC_TOP0_VAL, &clk->src_top0);
-       writel(CLK_SRC_TOP1_VAL, &clk->src_top1);
-       writel(CLK_SRC_DMC_VAL, &clk->src_dmc);
-       writel(CLK_SRC_LEFTBUS_VAL, &clk->src_leftbus);
-       writel(CLK_SRC_RIGHTBUS_VAL, &clk->src_rightbus);
+       writel(0x10, &clk->src_leftbus);
+       writel(0x10, &clk->src_rightbus);
+       writel(0x110, &clk->src_top0);
+       writel(0x1111000, &clk->src_top1);
+       writel(0x00011000, &clk->src_dmc);writel(CLK_SRC_FSYS_VAL, &clk->src_fsys);writel(CLK_SRC_PERIL0_VAL, &clk->src_peril0);writel(CLK_SRC_CAM_VAL, &clk->src_cam);writel(CLK_SRC_MFC_VAL, &clk->src_mfc);writel(CLK_SRC_G3D_VAL, &clk->src_g3d);
-       writel(CLK_SRC_LCD0_VAL, &clk->src_lcd0);sdelay(0x10000);-       writel(CLK_DIV_CPU0_VAL, &clk->div_cpu0);
-       writel(CLK_DIV_CPU1_VAL, &clk->div_cpu1);
-       writel(CLK_DIV_DMC0_VAL, &clk->div_dmc0);
-       writel(CLK_DIV_DMC1_VAL, &clk->div_dmc1);
-       writel(CLK_DIV_LEFTBUS_VAL, &clk->div_leftbus);
-       writel(CLK_DIV_RIGHTBUS_VAL, &clk->div_rightbus);
-       writel(CLK_DIV_TOP_VAL, &clk->div_top);
+       writel(0x1160730, &clk->div_cpu0);
+       writel(0x506, &clk->div_cpu1);
+       writel(0x111113, &clk->div_dmc0);
+       writel(0x1011713, &clk->div_dmc1);writel(CLK_DIV_FSYS1_VAL, &clk->div_fsys1);
-       writel(CLK_DIV_FSYS2_VAL, &clk->div_fsys2);
+       writel(0x4070047, &clk->div_fsys2);writel(CLK_DIV_FSYS3_VAL, &clk->div_fsys3);writel(CLK_DIV_PERIL0_VAL, &clk->div_peril0);writel(CLK_DIV_CAM_VAL, &clk->div_cam);writel(CLK_DIV_MFC_VAL, &clk->div_mfc);writel(CLK_DIV_G3D_VAL, &clk->div_g3d);
-       writel(CLK_DIV_LCD0_VAL, &clk->div_lcd0);/* Set PLL locktime */writel(PLL_LOCKTIME, &clk->apll_lock);
@@ -81,10 +78,10 @@ void system_clock_init(void)writel(PLL_LOCKTIME, &clk->epll_lock);writel(PLL_LOCKTIME, &clk->vpll_lock);-       writel(APLL_CON1_VAL, &clk->apll_con1);
-       writel(APLL_CON0_VAL, &clk->apll_con0);
-       writel(MPLL_CON1_VAL, &clk->mpll_con1);
-       writel(MPLL_CON0_VAL, &clk->mpll_con0);
+       writel(0x803800, &clk->apll_con1);
+       writel(0x80af0300, &clk->apll_con0);
+       writel(0x803800, &clk->mpll_con1);
+       writel(0x80640300, &clk->mpll_con0);writel(EPLL_CON1_VAL, &clk->epll_con1);writel(EPLL_CON0_VAL, &clk->epll_con0);writel(VPLL_CON1_VAL, &clk->vpll_con1);
(END)

修改drm的初始化

diff --git a/arch/arm/mach-exynos/dmc_init_exynos4.c b/arch/arm/mach-exynos/dmc_init_exynos4.c
old mode 100644
new mode 100755
index ecddc72..69e9fd6
--- a/arch/arm/mach-exynos/dmc_init_exynos4.c
+++ b/arch/arm/mach-exynos/dmc_init_exynos4.c
@@ -32,19 +32,19 @@ struct mem_timings mem = {.direct_cmd_msr = {DIRECT_CMD1, DIRECT_CMD2, DIRECT_CMD3, DIRECT_CMD4},
-       .timingref = TIMINGREF_VAL,
-       .timingrow = TIMINGROW_VAL,
-       .timingdata = TIMINGDATA_VAL,
-       .timingpower = TIMINGPOWER_VAL,
-       .zqcontrol = ZQ_CONTROL_VAL,
-       .control0 = CONTROL0_VAL,
-       .control1 = CONTROL1_VAL,
-       .control2 = CONTROL2_VAL,
-       .concontrol = CONCONTROL_VAL,
-       .prechconfig = PRECHCONFIG,
-       .memcontrol = MEMCONTROL_VAL,
-       .memconfig0 = MEMCONFIG0_VAL,
-       .memconfig1 = MEMCONFIG1_VAL,
+       .timingref =    0x000000bb,//TIMINGREF_VAL,
+       .timingrow =    0x7a46654f,//TIMINGROW_VAL,
+       .timingdata =   0x46400506,//TIMINGDATA_VAL,
+       .timingpower =  0x52000a3c,//TIMINGPOWER_VAL,
+       .zqcontrol =    0xe3854c03,//ZQ_CONTROL_VAL,
+       .control0 =     0x7110100b,//CONTROL0_VAL,
+       .control1 =     0xe0000086,//CONTROL1_VAL,
+       .control2 =     0x00000000,//CONTROL2_VAL,
+       .concontrol =   0x0fff333a,//CONCONTROL_VAL,
+       .prechconfig =  0xff000000,//PRECHCONFIG,
+       .memcontrol =   0x00302640,//MEMCONTROL_VAL,
+       .memconfig0 =   0x40c01333,//MEMCONFIG0_VAL,
+       .memconfig1 =   0x80e01323,//MEMCONFIG1_VAL,.dll_resync = FORCE_DLL_RESYNC,.dll_on = DLL_CONTROL_ON,};
@@ -124,6 +124,8 @@ static void dmc_init(struct exynos4_dmc *dmc)writel(mem.memconfig0, &dmc->memconfig0);writel(mem.memconfig1, &dmc->memconfig1);+       writel(0x8000001F, &dmc->ivcontrol);
+/* Config Precharge Policy */writel(mem.prechconfig, &dmc->prechconfig);/*

修改dmc的一些配置

diff --git a/arch/arm/mach-exynos/exynos4_setup.h b/arch/arm/mach-exynos/exynos4_setup.h
old mode 100644
new mode 100755
index 38735f0..4fb5444
--- a/arch/arm/mach-exynos/exynos4_setup.h
+++ b/arch/arm/mach-exynos/exynos4_setup.h
@@ -5,8 +5,11 @@* Copyright (C) 2011 Samsung Electronics*/-#ifndef _ORIGEN_SETUP_H
-#define _ORIGEN_SETUP_H
+//#ifndef _ORIGEN_SETUP_H
+//#define _ORIGEN_SETUP_H
+
+#ifndef _TINY4412_SETUP_H
+#define _TINY4412_SETUP_H#include <config.h>#include <asm/arch/cpu.h>
@@ -433,7 +436,7 @@ struct mem_timings {#define ABP_SFR_SLV1_SINGLE_ADDRMAP_START_OFFSET       0x828#define ABP_SFR_SLV1_SINGLE_ADDRMAP_END_OFFSET 0x830-#ifdef CONFIG_ORIGEN
+#if (defined CONFIG_ORIGEN) || (defined CONFIG_TINY4412)/* Interleave: 2Bit, Interleave_bit1: 0x15, Interleave_bit0: 0x7 */#define APB_SFR_INTERLEAVE_CONF_VAL    0x20001507#define APB_SFR_ARBRITATION_CONF_VAL   0x00000001
@@ -505,7 +508,7 @@ struct mem_timings {#define ADD_LAT_PALL           (1 << 6)#define MEM_TYPE_DDR3          (0x6 << 8)#define MEM_WIDTH_32           (0x2 << 12)
-#define NUM_CHIP_2             (1 << 16)
+#define NUM_CHIP_2             (0 << 16)#define BL_8                   (0x3 << 20)#define MEMCONTROL_VAL         (CLK_STOP_DISABLE | DPWRDN_DISABLE\| DPWRDN_TYPE | TP_DISABLE | DSREF_DIABLE\
@@ -514,16 +517,16 @@ struct mem_timings {#define CHIP_BANK_8            (0x3 << 0)
-#define CHIP_ROW_14            (0x2 << 4)
+#define CHIP_ROW_14            (0x3 << 4)#define CHIP_COL_10            (0x3 << 8)#define CHIP_MAP_INTERLEAVED   (1 << 12)
-#define CHIP_MASK              (0xe0 << 16)
+#define CHIP_MASK              (0xC0 << 16)#ifdef CONFIG_MIU_LINEAR#define CHIP0_BASE             (0x40 << 24)#define CHIP1_BASE             (0x60 << 24)#else
-#define CHIP0_BASE             (0x20 << 24)
-#define CHIP1_BASE             (0x40 << 24)
+#define CHIP0_BASE             (0x40 << 24)
+#define CHIP1_BASE             (0x80 << 24)#endif#define MEMCONFIG0_VAL         (CHIP_BANK_8 | CHIP_ROW_14 | CHIP_COL_10\| CHIP_MAP_INTERLEAVED | CHIP_MASK | CHIP0_BASE)
@@ -555,7 +558,7 @@ struct mem_timings {#define CONTROL2_VAL           0x00000000-#ifdef CONFIG_ORIGEN
+#if (defined CONFIG_ORIGEN) || (defined CONFIG_TINY4412)#define TIMINGREF_VAL          0x000000BB#define TIMINGROW_VAL          0x4046654f#define        TIMINGDATA_VAL          0x46400506
(END)

初始化串口0,作为打印输出口

diff --git a/arch/arm/mach-exynos/lowlevel_init.c b/arch/arm/mach-exynos/lowlevel_init.c
index 1e090fd..8cae6b9 100644
--- a/arch/arm/mach-exynos/lowlevel_init.c
+++ b/arch/arm/mach-exynos/lowlevel_init.c
@@ -216,14 +216,17 @@ int do_lowlevel_init(void)if (actions & DO_CLOCKS) {system_clock_init();#ifdef CONFIG_DEBUG_UART
-#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL_SUPPORT)) || \
+//#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL_SUPPORT)) || \!defined(CONFIG_SPL_BUILD)
-               exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
+               exynos_pinmux_config(PERIPH_ID_UART0, PINMUX_FLAG_NONE);debug_uart_init();
-#endif
+               printascii("UART OK \n\r");
+//#endif#endifmem_ctrl_init(actions & DO_MEM_RESET);
+               printascii("mem ctrl init ok \n\r");tzpc_init();
+               printascii("tzpc_init ok \n\r");}

修改trust zone ,否则有些总线不能用

diff --git a/arch/arm/mach-exynos/tzpc.c b/arch/arm/mach-exynos/tzpc.c
old mode 100644
new mode 100755
index abe8e7f..63605d5
--- a/arch/arm/mach-exynos/tzpc.c
+++ b/arch/arm/mach-exynos/tzpc.c
@@ -17,10 +17,7 @@ void tzpc_init(void)start = samsung_get_base_tzpc();-       if (cpu_is_exynos5())
-               end = start + ((EXYNOS5_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);
-       else if (cpu_is_exynos4())
-               end = start + ((EXYNOS4_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);
+       end = start + ((EXYNOS4_NR_TZPC_BANKS - 1) * TZPC_BASE_OFFSET);for (addr = start; addr <= end; addr += TZPC_BASE_OFFSET) {tzpc = (struct exynos_tzpc *)addr;
@@ -30,11 +27,7 @@ void tzpc_init(void)writel(DECPROTXSET, &tzpc->decprot0set);writel(DECPROTXSET, &tzpc->decprot1set);
-
-               if (cpu_is_exynos5() && (addr == end))
-                       break;
-
-               writel(DECPROTXSET, &tzpc->decprot2set);
+               writel(0xbd,        &tzpc->decprot2set);writel(DECPROTXSET, &tzpc->decprot3set);}}

仿照board/samsung/origen 文件夹增加board/samsung/tiny4412文件夹,并修改里面的文件名。

board/samsung/tiny4412/Kconfig 
 board/samsung/tiny4412/MAINTAINERS
 board/samsung/tiny4412/Makefile 
 board/samsung/tiny4412/tiny4412.c 
 board/samsung/tiny4412/tools/mktiny4412spl.c

修改Kconfig文件

diff --git a/board/samsung/tiny4412/Kconfig b/board/samsung/tiny4412/Kconfig
new file mode 100644
index 0000000..04658fe
--- /dev/null
+++ b/board/samsung/tiny4412/Kconfig
@@ -0,0 +1,16 @@
+if TARGET_TINY4412
+
+config TINY4412
+       default y
+       bool "For CONFIG_TINY4412"
+
+config SYS_BOARD
+       default "tiny4412"
+
+config SYS_VENDOR
+       default "samsung"
+
+config SYS_CONFIG_NAME
+       default "tiny4412"
+
+endif

增加如下文件

diff --git a/board/samsung/tiny4412/MAINTAINERS b/board/samsung/tiny4412/MAINTAINERS
new file mode 100755
index 0000000..4f2fd06
--- /dev/null
+++ b/board/samsung/tiny4412/MAINTAINERS
@@ -0,0 +1,6 @@
+TINY4412 BOARD
+M:     Song Chong <1972433980@qq.com>
+S:     Maintained
+F:     board/samsung/tiny4412/
+F:     include/configs/tiny4412.h
+F:     configs/tiny4412_defconfig
diff --git a/board/samsung/tiny4412/tiny4412.c b/board/samsung/tiny4412/tiny4412.c
new file mode 100755
index 0000000..eca942a
--- /dev/null
+++ b/board/samsung/tiny4412/tiny4412.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/periph.h>
+#include <asm/arch/pinmux.h>
+#include <usb.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 get_board_rev(void)
+{
+       return 0;
+}
+
+int exynos_init(void)
+{
+       return 0;
+}
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+       return 0;
+}
+
+#ifdef CONFIG_BOARD_EARLY_INIT_F
+int exynos_early_init_f(void)
+{
+       return 0;
+}
+#endif
diff --git a/board/samsung/tiny4412/tools/mktiny4412spl.c b/board/samsung/tiny4412/tools/mktiny4412spl.c
new file mode 100644
index 0000000..f4be867
--- /dev/null
+++ b/board/samsung/tiny4412/tools/mktiny4412spl.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define BUFSIZE                        (16*1024)
+#define IMG_SIZE               (16*1024)
+#define SPL_HEADER_SIZE                16
+#define FILE_PERM              (S_IRUSR | S_IWUSR | S_IRGRP \
+                               | S_IWGRP | S_IROTH | S_IWOTH)
+#define SPL_HEADER             "S5PC210 HEADER  "
+/*
+* Requirement:
+* IROM code reads first 14K bytes from boot device.
+* It then calculates the checksum of 14K-4 bytes and compare with data at
+* 14K-4 offset.
+*
+* This function takes two filenames:
+* IN  "u-boot-spl.bin" and
+* OUT "$(BOARD)-spl.bin as filenames.
+* It reads the "u-boot-spl.bin" in 16K buffer.
+* It calculates checksum of 14K-4 Bytes and stores at 14K-4 offset in buffer.
+* It writes the buffer to "$(BOARD)-spl.bin" file.
+*/
+
+int main(int argc, char **argv)
+{
+       int i, len;
+       unsigned char buffer[BUFSIZE] = {0};
+       int ifd, ofd;
+       unsigned int checksum = 0, count;
+
+       if (argc != 3) {
+               printf(" %d Wrong number of arguments\n", argc);
+               exit(EXIT_FAILURE);
+       }
+
+       ifd = open(argv[1], O_RDONLY);
+       if (ifd < 0) {
+               fprintf(stderr, "%s: Can't open %s: %s\n",
+                       argv[0], argv[1], strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM);
+       if (ofd < 0) {
+               fprintf(stderr, "%s: Can't open %s: %s\n",
+                       argv[0], argv[2], strerror(errno));
+               if (ifd)
+                       close(ifd);
+               exit(EXIT_FAILURE);
+       }
+
+       len = lseek(ifd, 0, SEEK_END);
+       lseek(ifd, 0, SEEK_SET);
+
+       memcpy(&buffer[0], SPL_HEADER, SPL_HEADER_SIZE);
+
+       count = (len < (IMG_SIZE - SPL_HEADER_SIZE))
+               ? len : (IMG_SIZE - SPL_HEADER_SIZE);
+
+       if (read(ifd, buffer + SPL_HEADER_SIZE, count) != count) {
+               fprintf(stderr, "%s: Can't read %s: %s\n",
+                       argv[0], argv[1], strerror(errno));
+
+               if (ifd)
+                       close(ifd);
+               if (ofd)
+                       close(ofd);
+
+               exit(EXIT_FAILURE);
+       }
+
+       for (i = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)
+               checksum += buffer[i+16];
+
+       *(unsigned long *)buffer ^= 0x1f;
+       *(unsigned long *)(buffer+4) ^= checksum;
+
+       for (i = 1; i < SPL_HEADER_SIZE; i++)
+               buffer[i] ^= buffer[i-1];
+
+       if (write(ofd, buffer, BUFSIZE) != BUFSIZE) {
+               fprintf(stderr, "%s: Can't write %s: %s\n",
+                       argv[0], argv[2], strerror(errno));
+
+               if (ifd)
+                       close(ifd);
+               if (ofd)
+                       close(ofd);
+
+               exit(EXIT_FAILURE);
+       }
+
+       if (ifd)
+               close(ifd);
+       if (ofd)
+               close(ofd);
+
+       return EXIT_SUCCESS;
+}

增加个打印,看uboot是否跑起来

diff --git a/common/board_f.c b/common/board_f.c
index 149a722..f0fbf13 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -43,7 +43,7 @@#include <asm/sections.h>#include <dm/root.h>#include <linux/errno.h>
-
+#include <debug_uart.h>/** Pointer to initial global data area*
@@ -985,6 +985,7 @@ static const init_fnc_t init_sequence_f[] = {void board_init_f(ulong boot_flags){
+       printascii("uboot runnig.\r\n");gd->flags = boot_flags;gd->have_console = 0;

增加配置文件tiny4412_defonfig

diff --git a/configs/tiny4412_defconfig b/configs/tiny4412_defconfig
new file mode 100755
index 0000000..06b35fb
--- /dev/null
+++ b/configs/tiny4412_defconfig
@@ -0,0 +1,49 @@
+CONFIG_ARM=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_TARGET_TINY4412=y
+CONFIG_SYS_TEXT_BASE=0x43E00000
+CONFIG_ARCH_EXYNOS4=y
+#CONFIG_TARGET_ORIGEN=y
+CONFIG_SPL=y
+CONFIG_IDENT_STRING=" for TINY4412"
+CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_USE_BOOTCOMMAND is not set
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_SPL_FRAMEWORK is not set
+CONFIG_SYS_PROMPT="TINY4412 # "
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_THOR_DOWNLOAD=y
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_NET is not set
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+# CONFIG_CMD_MISC is not set
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="exynos4412-tiny4412"
+CONFIG_DFU_MMC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_S5P=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Samsung"
+CONFIG_USB_GADGET_VENDOR_NUM=0x04e8
+CONFIG_USB_GADGET_PRODUCT_NUM=0x6601
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_USB_FUNCTION_THOR=y
+# CONFIG_REGEX is not set

修改串口初始化寄存器

diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index e3160cf..2de62f0 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -62,12 +62,12 @@ static const int udivslot[] = {static void __maybe_unused s5p_serial_init(struct s5p_uart *uart){/* enable FIFOs, auto clear Rx FIFO */
-       writel(0x3, &uart->ufcon);
+       writel(0x11, &uart->ufcon);writel(0, &uart->umcon);/* 8N1 */writel(0x3, &uart->ulcon);/* No interrupts, no DMA, pure polling */
-       writel(0x245, &uart->ucon);
+       writel(0x3c5, &uart->ucon);}

增加include/configs/tiny4412.h

diff --git a/include/configs/tiny4412.h b/include/configs/tiny4412.h
new file mode 100755
index 0000000..bc67d97
--- /dev/null
+++ b/include/configs/tiny4412.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics
+ *
+ * Configuration settings for the SAMSUNG TINY4412 (EXYNOS4412) board.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_TINY4412_H
+#define __CONFIG_TINY4412_H
+
+#include <configs/exynos4-common.h>
+
+/* High Level Configuration Options */
+#define CONFIG_TINY4412            1
+
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_DEBUG_UART
+#define CONFIG_DEBUG_UART_S5P
+#define CONFIG_DEBUG_UART_BASE 0x13800000    /* UART0 base address  */
+#define CONFIG_DEBUG_UART_CLOCK (100000000)    /* SCLK_UART0 is 100MHz  */
+
+#define CONFIG_SYS_DCACHE_OFF        1
+
+/* ORIGEN has 4 bank of DRAM */
+#define CONFIG_NR_DRAM_BANKS        4
+#define CONFIG_SYS_SDRAM_BASE        0x40000000
+#define PHYS_SDRAM_1            CONFIG_SYS_SDRAM_BASE
+#define SDRAM_BANK_SIZE            (256 << 20)    /* 256 MB */
+
+/* memtest works on */
+#define CONFIG_SYS_MEMTEST_START    CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END        (CONFIG_SYS_SDRAM_BASE + 0x6000000)
+#define CONFIG_SYS_LOAD_ADDR        (CONFIG_SYS_SDRAM_BASE + 0x3E00000)
+
+#define CONFIG_MACH_TYPE        MACH_TYPE_TINY4412
+
+/* select serial console configuration */
+#define CONFIG_SERIAL2
+#define CONFIG_BAUDRATE            115200
+
+/* Console configuration */
+
+#define CONFIG_DEFAULT_CONSOLE        "console=ttySAC0,115200n8\0"
+
+#define CONFIG_SYS_MEM_TOP_HIDE    (1 << 20)    /* ram console */
+
+#define CONFIG_SYS_MONITOR_BASE    0x00000000
+
+/* Power Down Modes */
+#define S5P_CHECK_SLEEP            0x00000BAD
+#define S5P_CHECK_DIDLE            0xBAD00000
+#define S5P_CHECK_LPA            0xABAD0000
+
+/* MMC SPL */
+#define COPY_BL2_FNPTR_ADDR    0x02020030
+/* Because bl1 will copy bl2(spl) to iram address 0x02023400 */
+#define CONFIG_SPL_TEXT_BASE    0x02023400
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+    "loadaddr=0x40007000\0" \
+    "rdaddr=0x48000000\0" \
+    "dtaddr=0x42000000\0" \
+    "kerneladdr=0x40007000\0" \
+    "ramdiskaddr=0x48000000\0" \
+    "dtbaddr=0x42000000\0" \
+    "console=ttySAC0,115200n8\0" \
+    "mmcdev=0\0" \
+    "bootenv=uEnv.txt\0" \
+    "loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}\0" \
+    "importbootenv=echo Importing environment from mmc ...; " \
+        "env import -t $loadaddr $filesize\0" \
+        "loadbootscript=load mmc ${mmcdev} ${loadaddr} boot.scr\0" \
+        "bootscript=echo Running bootscript from mmc${mmcdev} ...; " \
+                "source ${loadaddr}\0"
+#define CONFIG_BOOTCOMMAND \
+    "if mmc rescan; then " \
+        "echo SD/MMC found on device ${mmcdev};" \
+        "if run loadbootenv; then " \
+            "echo Loaded environment from ${bootenv};" \
+            "run importbootenv;" \
+        "fi;" \
+        "if test -n $uenvcmd; then " \
+            "echo Running uenvcmd ...;" \
+            "run uenvcmd;" \
+        "fi;" \
+        "if run loadbootscript; then " \
+            "run bootscript; " \
+        "fi; " \
+    "fi;" \
+    "load mmc ${mmcdev} ${loadaddr} uImage;" \
+    "load mmc ${mmcdev} ${rdaddr} ramdisk.img;"\
+    "load mmc ${mmcdev} ${dtaddr} exynos4412-tiny4412.dtb; bootm ${loadaddr} "
+
+#define CONFIG_IDENT_STRING        " for TINY4412"
+
+#define CONFIG_CLK_1000_400_200
+
+/* MIU (Memory Interleaving Unit) */
+#define CONFIG_MIU_2BIT_21_7_INTERLEAVED
+
+/*
+ *    SD MMC layout:
+ *    +------------+------------------------------------------------------------+
+ *    |                                                                         |
+ *    |            |            |               |              |                |
+ *    |   512B     |   8K(bl1)  |    16k(bl2)   |   16k(ENV)   |  512k(u-boot)  |
+ *    |            |            |               |              |                |
+ *    |                                                                         |
+ *    +------------+------------------------------------------------------------+
+ *
+ */
+
+#define CONFIG_SYS_MMC_ENV_DEV        0
+#define CONFIG_ENV_SIZE            (16 << 10)    /* 16 KB */
+#define RESERVE_BLOCK_SIZE        (512)
+#define BL1_SIZE            (8 << 10)  /*16 K reserved for BL1*/
+#define BL2_SIZE            (16 << 10) /*16 k reserved for BL2*/
+#define CONFIG_ENV_OFFSET        (RESERVE_BLOCK_SIZE + BL1_SIZE + BL2_SIZE)
+
+#define CONFIG_SPL_LDSCRIPT    "board/samsung/common/exynos-uboot-spl.lds"
+#define CONFIG_SPL_MAX_FOOTPRINT    (14 * 1024)
+
+#define CONFIG_SYS_INIT_SP_ADDR        0x02040000
+
+/* U-Boot copy size from boot Media to DRAM.*/
+#define COPY_BL2_SIZE          0x80000
+#define BL2_START_OFFSET       ((CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)/512)
+#define BL2_SIZE_BLOC_COUNT    (COPY_BL2_SIZE/512)
+
+/* #define UBOOT_DEBUG_20151226 */
+
+#endif    /* __CONFIG_H */

增加个自动化编译的脚本,方便编译

diff --git a/make.sh b/make.sh
new file mode 100755
index 0000000..579407d
--- /dev/null
+++ b/make.sh
@@ -0,0 +1,2 @@
+make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
+make tiny4412_defconfig && make

增加个自动烧写SD卡,制作卡启动的脚本。其中/dev/sdb是sd卡被编译uboot的linux机器识别为sdb1.

不同的 机器可能识别出来不一样,有的是/dev/sdc等,通过df 命令可以查看。

diff --git a/run.sh b/run.sh
new file mode 100755
index 0000000..925b7ad
--- /dev/null
+++ b/run.sh
@@ -0,0 +1,7 @@
+echo -e "\033[45m start fusing \033[0m"
+
+cd sd_fuse/tiny4412/
+./sd_fusing.sh /dev/sdb
+cd ../..
+
+echo -e "\033[45m fusing over \033[0m"

友善之臂给出的uboot中,有个sd_fuse文件夹,需要拷贝过来,我放在uboot的根目录下。

V310-EVT1-mkbl2.c 用于生产mkbl2工具,里面有个地方需要修改。

diff --git a/sd_fuse/V310-EVT1-mkbl2.c b/sd_fuse/V310-EVT1-mkbl2.c
new file mode 100755
index 0000000..f754f9f
--- /dev/null
+++ b/sd_fuse/V310-EVT1-mkbl2.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main (int argc, char *argv[])
+{
+       FILE            *fp;
+       unsigned char   src;
+       char            *Buf, *a;
+       int             BufLen;
+       int             nbytes, fileLen;
+       unsigned int    checksum = 0;
+       int             i;
+
+       if (argc != 4)
+       {
+               printf("Usage: mkbl1 <source file> <destination file> <size> \n");
+               return -1;
+       }
+
+       BufLen = atoi(argv[3]);
+       Buf = (char *)malloc(BufLen);
+       memset(Buf, 0x00, BufLen);
+
+       fp = fopen(argv[1], "rb");
+       if( fp == NULL)
+       {
+               printf("source file open error\n");
+               free(Buf);
+               return -1;
+       }
+
+       fseek(fp, 0L, SEEK_END);
+       fileLen = ftell(fp);
+       fseek(fp, 0L, SEEK_SET);
+/*
+       if ( BufLen > fileLen )
+       {
+               printf("Usage: unsupported size\n");
+               free(Buf);
+               fclose(fp);
+               return -1;
+       }
+*/
+       //nbytes = fread(Buf, 1, BufLen, fp);
+       if(BufLen > fileLen)
+               nbytes = fread(Buf, 1, fileLen, fp);
+       else
+               nbytes = fread(Buf, 1, BufLen, fp);
+/*
+       if ( nbytes != BufLen )
+       {
+               printf("source file read error\n");
+               free(Buf);
+               fclose(fp);
+               return -1;
+       }
+*/
+       fclose(fp);
+
+       for(i = 0;i < (14 * 1024) - 4;i++)
+       {
+               checksum += (unsigned char)(Buf[i]);
+       }
+       *(unsigned int*)(Buf+i) = checksum;
+
+       fp = fopen(argv[2], "wb");
+       if (fp == NULL)
+       {
+               printf("destination file open error\n");
+               free(Buf);
+               return -1;
+       }
+
+       a       = Buf;
+       nbytes  = fwrite( a, 1, BufLen, fp);
+
+       if ( nbytes != BufLen )
+       {
+               printf("destination file write error\n");
+               free(Buf);
+               fclose(fp);
+               return -1;
+       }
+
+       free(Buf);
+       fclose(fp);
+
+       return 0;
+}
(END)

sd_fusing.sh 用于将uboot 和bl2.bin等烧写到SD卡上。

diff --git a/sd_fuse/tiny4412/sd_fusing.sh b/sd_fuse/tiny4412/sd_fusing.sh
new file mode 100755
index 0000000..e5e6cdb
--- /dev/null
+++ b/sd_fuse/tiny4412/sd_fusing.sh
@@ -0,0 +1,91 @@
+#
+# Copyright (C) 2011 Samsung Electronics Co., Ltd.
+#              http://www.samsung.com/
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+####################################
+
+if [ -z $1 ]
+then
+    echo "usage: ./sd_fusing.sh <SD Reader's device file>"
+    exit 0
+fi
+
+if [ -b $1 ]
+then
+    echo "$1 reader is identified."
+else
+    echo "$1 is NOT identified."
+    exit 0
+fi
+
+####################################
+#<verify device>
+
+BDEV_NAME=`basename $1`
+BDEV_SIZE=`cat /sys/block/${BDEV_NAME}/size`
+
+if [ ${BDEV_SIZE} -le 0 ]; then
+       echo "Error: NO media found in card reader."
+       exit 1
+fi
+
+if [ ${BDEV_SIZE} -gt 32000000 ]; then
+       echo "Error: Block device size (${BDEV_SIZE}) is too large"
+       exit 1
+fi
+
+####################################
+# check files
+
+E4412_SPL=../../spl/u-boot-spl.bin
+E4412_UBOOT=../../u-boot-dtb.bin
+MKBL2=../mkbl2
+
+if [ ! -f ${E4412_UBOOT} ]; then
+       echo "Error: u-boot.bin NOT found, please build it & try again."
+       exit -1
+fi
+
+if [ ! -f ${MKBL2} ]; then
+       echo "Error: can not find host tool - mkbl2, stop."
+       exit -1
+fi
+
+#<make bl2>
+${MKBL2} ${E4412_SPL} bl2.bin 14336
+
+####################################
+# fusing images
+
+signed_bl1_position=1
+bl2_position=17
+uboot_position=81
+
+#<BL1 fusing>
+echo "---------------------------------------"
+echo "BL1 fusing"
+dd iflag=dsync oflag=dsync if=./E4412_N.bl1.bin of=$1 seek=$signed_bl1_position
+
+#<BL2 fusing>
+echo "---------------------------------------"
+echo "BL2 fusing"
+dd iflag=dsync oflag=dsync if=./bl2.bin of=$1 seek=$bl2_position
+
+#<u-boot fusing>
+echo "---------------------------------------"
+echo "u-boot fusing"
+dd iflag=dsync oflag=dsync if=${E4412_UBOOT} of=$1 seek=$uboot_position
+
+#<flush to disk>
+sync
+
+####################################
+#<Message Display>
+echo "---------------------------------------"
+echo "U-boot image is fused successfully."
+echo "Eject SD card and insert it again."
+

移植完毕.

编译

./make.sh

烧写

./run.sh

烧写uboot到sd卡中。

随后将 uImage、ramdisk.img和exynos4412-tiny4412.dtb拷贝进SD卡(在linux上用脚本烧写完uboot后,将sd卡插在windows上,直接将这个三个文件拷贝进sd卡),这三个文件的下载地址为:http://files.cnblogs.com/files/AP0904225/tiny4412-test-image.tar.gz

上电测试,uboot 2019跑起来,并且启动了内核。

参考:https://www.cnblogs.com/pengdonglin137/p/5080645.html

https://www.cnblogs.com/LoTGu/category/872380.html

https://blog.csdn.net/qq_33160790/article/category/7117737

tiny4412移植uboot-2019-01(三)相关推荐

  1. 移植u-boot v2018

    本篇文章阐述移植 u-boot v2018.01 至 S5PV210 开发板上的主要流程和细节.市场上的S5PV210开发板,均是基于三星smdkv210公版平台山寨出来的.我使用的GEC210开发板 ...

  2. linux 485串口运行一段时间之后 无反应,Supper tiny4412 用友善之臂官方文档资料移植uboot出错  出现OK后就没反应了 求大神解救...

    一. 为了方便大家查看我的问题,我把详细过程记录一下,希望大家能看出问题所在. 二. uboot 编译环境 :32位window7 的虚拟机Vmware9中的Ubuntu14.04,交叉编译工具arm ...

  3. 嵌入式ARM64 uboot 2022.01 移植

    ​平台:orangepi4 rockchip rk3399 LPDDR4 4G eMMC 16G 系统:ubuntu 20.04 主要介绍移植最新的bootloader到RK3399,我使用的是ora ...

  4. 【TINY4412】U-BOOT移植笔记:(9)SD卡启动U-BOOT

    [TINY4412]U-BOOT移植笔记:(9)SD卡启动U-BOOT 宿主机 : 虚拟机 Ubuntu 16.04 LTS / X64 目标板[底板]: Tiny4412SDK - 1506 目标板 ...

  5. tiny4412编译与移植uboot

    tiny4412编译与移植U-Boot 1.uboot简介   U-Boot 是一个主要用于嵌入式系统的引导加载程序,可以支持多种不同的计算机系统结构,包括PPC.ARM.AVR32.MIPS.x86 ...

  6. T2080 U-BOOT与OS内核移植 u-boot移植篇(一)——创建新目标板的u-boot工程

    T2080 U-BOOT与OS内核移植 u-boot移植篇(一)--创建新目标板的u-boot工程 一.创建新目标板文件夹并修改相应文件 1.创建新目标板文件夹 2.修改t2080tpm文件夹中的相应 ...

  7. 移植u-boot-2012.04.01到JZ2440(二:分析启动流程)

    目录 2. 分析启动流程 2.1 u-boot.lds链接脚本 2.2 start.S启动文件     2.2.1 设置异常向量表     2.2.2 设置SVC管理模式.关看门狗.关中断.设置时钟频 ...

  8. tiny4412搭建linux开发环境,[Tiny4412] 移植 Linux4.4 到 Tiny4412 开发板上

    一. 前言 一直以来都是基于 Linux-2.6 内核学习嵌入式,但是工作之后发现,主流的 kernel 早已经不再使用 platform device 结构去描述设备信息了,而是换成了更为简洁的 d ...

  9. U-Boot的移植U-Boot Practically Porting Guide(转)

    本文转自:http://blog.csdn.net/hongkaicsu/article/details/5187015 U-Boot的移植之(一)基础篇:添加新的目标板定义 本文使用最新的U-Boo ...

最新文章

  1. 边城高级中学2021届高考成绩查询,湖南省花垣县边城高级中学2021届高三第二学期学科素养测试英语试题及答案.doc...
  2. 华农软件工程实验报告_华南农业大学的软件工程怎么样?
  3. linux的vi把文件合并一行,学习Vim合并行的方法和技巧
  4. python返回菜单_返回上一菜单
  5. pytorch 数据类型
  6. BZOJ 1041 数学
  7. UBUNTU安装 SSH 服务
  8. 15 岁黑进系统,发挑衅邮件意外获 Offer,不惑之年捐出全部财产,Twitter CEO 太牛了!...
  9. linux 测试t3协议,Yealink网络电话SIP-T38G本地文件包含漏洞
  10. jQuery中的join方法
  11. 51单片机最小系统的检查
  12. 解决小程序图片上传问题
  13. Yolo 一小时学会基本操作
  14. 摆脱无效报警?十年运维监控报警优化经验总结
  15. Groundhog Chasing Death
  16. 左边是地狱右边也是地狱_我担任地狱首席执行官的时间
  17. 2019年1月即将上映的热门电影推荐,赶快来先睹为快吧!
  18. 《花千骨》绝美外景剧照 赵丽颖霍建华仙气足
  19. 「 神器 」绝不简单的截图神器
  20. 彻底搞懂 RxJava

热门文章

  1. 适合做引流的产品有什么特点?引流产品必须具备几个特点
  2. Mac配置ll的查看命令
  3. 佛说,是我们自己苦了自己
  4. 《知识图谱》赵军 学习笔记
  5. h61 nvme硬盘_移动硬盘怎么选?看完这篇不踩坑
  6. 手工重建复合文档(.doc;xls,ppt)文件头,修复文件全过程
  7. Java 导出CSV文件及实现web下载CSV
  8. 基于SSM整合的驾照在线考试系统
  9. 交换机POE技术知识大全
  10. FPGA入门-腾讯云布道师团队-专题视频课程