300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 创客exynos-fs4412系统移植-(uboot 内核 文件系统)

创客exynos-fs4412系统移植-(uboot 内核 文件系统)

时间:2019-08-07 01:16:26

相关推荐

创客exynos-fs4412系统移植-(uboot 内核 文件系统)

fs4412系统移植学习笔记

环境:

ubuntu 14.04 发行版FS4412 实验平台交叉编译工具:arm-none-linux-gnueabi-gcc: 4.8.5

目录

fs4412系统移植学习笔记(A) uboot移植一 uboot源码结构概括源码结构平台相关代码平台无关代码配置文件,帮助文档,示例程序,帮助等二 uboot配置与编译1. fs4412平台配置1.1 下载uboot源码1.2 解压uboot源码1.3指定交叉编译工具信息1.4 添加Board信息1.5 编译uboot2. 添加三星加密引导方式2.1 添加三星加密引导方式文件3. 添加调试代码与编译脚本3.1 添加调试代码3.2 添加编译脚本3.3 编译uboot4. 实现串口输出4.1 修改UART源码4.2 编译uboot三 SD卡启动盘制作3.1 bin文件制作3.2 烧写bin文件到SD卡3.3 测试uboot四 网卡移植4.1 修改网络初始化代码4.2 修改网络配置代码4.3 编译与测试uboot五 EMMC移植5.1 修改EMMC初始化代码5.2 添加EMMC命令5.3 修改EMMC配置代码5.4编译与测试uboot六 电源管理移植6.1 修改电源管理相关代码6.2 编译与测试uboot(B) Linux内核移植一 Linux源码下载(linux-3.14.tar.xz)二 平台配置1. 平台配置1.1 指定编译器1.2 指定使用的处理器2. uart配置2.1 配置工具2.2 修改输出串口三 网卡驱动移植1. 选配网卡2. 配置NFS3. 编译内核( C ) 设备树移植一 平台配置二 修改配置1 修改网卡配置2 修改时钟配置3 修改EMMC相关配置三 编译与测试1 编译内核和设备树2 测试内核和设备树( D ) 根文件系统移植一 busybox工具二 配置根文件系统1 进入 busybox 配置界面2 配置busybox3 编译与安装busybox4 移植根文件4.1 查看文件4.2 拷贝库文件4.3 删除库文件中的静态库4.4 拷贝etc目录4.5 给 etc/init.d/下的 rcS 脚本添加可执行权限4.6 创建其他目录4.7 拷贝根文件系统

(A) uboot移植

一 uboot源码结构概括

使用uboot引导启动Linux是Linux嵌入式开发中最常使用的方式

uboot源码下载

http://www.denx.de/wiki/U-Boot/

本次移植使用u-boot-.01版本为什么使用uboot 代码结构清晰支持丰富的处理器与开发板,易于移植支持丰富的用户命令支持丰富的网络协议支持丰富的文件系统支持丰富的设备驱动更新活跃、用户较多、资料丰富开放源代码较高的稳定性不具有通用性(不同的处理器、开发板uboot不可通用)

源码结构

u-boot-.01版本源码结构

平台相关代码

即与CPU架构或开发板硬件相关的源码,硬件的改动对应的代码也需要进行修改

平台无关代码

配置文件,帮助文档,示例程序,帮助等

二 uboot配置与编译

1. fs4412平台配置

1.1 下载uboot源码

在uboot官网下载uboot源码(u-boot-.01.tar.bz2)

ftp://ftp.denx.de/pub/u-boot/

1.2 解压uboot源码

拷贝uboot源码到工作目录下,解压并进入顶层目录

$ tar xvf u-boot-.01.tar.bz2$ cd u-boot-.01/

1.3指定交叉编译工具信息

打开Makefile,在Makefile中指定要使用的处理器架构及交叉编译工具

ifeq ($(HOSTARCH),$(ARCH))CROSS_COMPILE ?=endif

修改为如下内容,然后保存退出

ifeq (arm,arm)CROSS_COMPILE ?= arm-none-linux-gnueabi-endif

1.4 添加Board信息

在uboot源码中选择samsung公司的origen开发板对其进行修改,以适配fs4412开发板

a - 复制origen开发板源码目录复制为fs4412

$ cp -rf board/samsung/origen/ board/samsung/fs4412$ mv board/samsung/fs4412/origen.c board/samsung/fs4412/fs4412.c

修改fs4412目录下Makefile内容:

将:

ifndef CONFIG_SPL_BUILDCOBJS+= origen.oendif

修改为如下内容,然后保存退出

ifndef CONFIG_SPL_BUILDCOBJS+= fs4412.oendif

b - 拷贝origen相关的头文件并重命名

cp include/configs/origen.h include/configs/fs4412.h

修改fs4412.h信息:

将:

#define CONFIG_SYS_PROMPT"ORIGEN # "

#define CONFIG_IDENT_STRING" for ORIGEN"

修改为:

#define CONFIG_SYS_PROMPT"fs4412 # "

#define CONFIG_IDENT_STRING" for fs4412"

c - 打开uboot源码顶层目录下的boards.cfg

在:

origenarm armv7origen samsungexynos

后添加fs4412信息,然后保存退出:

fs4412arm armv7fs4412 samsungexynos

1.5 编译uboot

到此为止就可以指定Board信息了,在uboot顶层目录执行:

$ make fs4412_config

编译uboot

$ make

编译完成后会在源码顶层目录下生成u-boot.bin文件,但该文件还不能在我们的开发板 上运行,因为以上操作我们只是把origen相关的文件的名字改成了fs4412,使uboot能 识别fs4412开发板,但文件中的代码还是origen的,和我们的开发板不匹配,所以我 们还需要进一步进行修改和配置

2. 添加三星加密引导方式

考虑芯片启动的安全性,Exynos4412需要三星提供的初始引导加密后我们的u-boot才 能被引导运行,所以我们需要在uboot源码中添加三星提供的加密处理代码

2.1 添加三星加密引导方式文件

将资料中“移植相关文件”下的

sdfuse_q

CodeSign4SecureBoot

目录拷贝到uboot源 码的顶层目录下*这之后不要执行make clean或make distclean,这会将加密文件清除)

因为添加的加密文件也要编译,所以对应的Makefile也要修改

在:

$(obj)u-boot.bin:$(obj)u-boot$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@$(BOARD_SIZE_CHECK)

后添加如下内容,保存退出:

@#./mkuboot@split -b 14336 u-boot.bin bl2@+make -C sdfuse_q/@#cp u-boot.bin u-boot-4212.bin@#cp u-boot.bin u-boot-4412.bin@#./sdfuse_q/add_sign@./sdfuse_q/chksum@./sdfuse_q/add_padding@rm bl2a*@echo

3. 添加调试代码与编译脚本

3.1 添加调试代码

很多时候我们不确定uboot是否已经在板子上运行,所以我们在uboot源码中添加一段 代码使板子上的LED点亮,这样如果看到LED亮的话就表示uboot已经在运行了

打开uboot启动后的第一段代码

$ vi arch/arm/cpu/armv7/start.S

在第134行后添加如下代码(即点亮LED2),然后保存退出

ldr r0, =0x11000c40ldr r1, [r0]bic r1, r1, #0xf0000000orr r1, r1, #0x10000000str r1, [r0]ldr r0, =0x11000c44mov r1, #0xffstr r1, [r0]

3.2 添加编译脚本

使用make命令编译时只链接uboot源码中的相关代码,而我们添加的初始引导加密的代码不会被连接到u-boot.bin中,所以这里我们自己编写编译脚本build.sh,这个脚本中除了对uboot源码进行配置和编译外还将初始引导加密代码链接到了u-boot.bin上, 最终生成一个完成的uboot镜像u-boot-fs4412.bin

将资料中“移植相关文件”下的build.sh拷贝到uboot源码的顶层目录下

给编译脚本添加可执行权限

$ chmod 777 build.sh

3.3 编译uboot

通过脚本编译uboot源码

$ ./build.sh

编译完成后在源码的顶层目录下会生成“u-boot-fs4412.bin”

4. 实现串口输出

虽然uboot已经能在开发板上加载运行,但是此时的uboot还不能在终端上打印信息, 原因在于uboot源码中对UART的配置与我们实际的硬件不匹配

4.1 修改UART源码

$ vi board/samsung/fs4412/lowlevel_init.S

lowlevel_init:

后添加如下内容(初始化临时栈)

ldr sp,=0x02060000

beqwakeup_reset

后添加如下内容(关闭看门狗)

#if 1ldr r0, =0x1002330cldr r1, [r0]orr r1, r1, #0x300str r1, [r0]ldr r0, =0x11000c08ldr r1, =0x0str r1, [r0]/* Clear MASK_WDT_RESET_REQUEST */ldr r0, =0x1002040cldr r1, =0x00str r1, [r0]#endif

uart_asm_init:/* setup UART0-UART3 GPIOs (part1) */movr0, r7ldrr1, =EXYNOS4_GPIO_A0_CON_VALstrr1, [r0, #EXYNOS4_GPIO_A0_CON_OFFSET]ldrr1, =EXYNOS4_GPIO_A1_CON_VALstrr1, [r0, #EXYNOS4_GPIO_A1_CON_OFFSET]

后添加如下内容(UART初始化)

ldrr0, =0x10030000ldrr1, =0x666666ldrr2, =CLK_SRC_PERIL0_OFFSETstrr1, [r0, r2]ldrr1, =0x777777ldrr2, =CLK_DIV_PERIL0_OFFSETstrr1, [r0, r2]

注释掉

bl uart_asm_init

后的一条语句,然后保存退出

#if 0bl tzpc_init#endif

4.2 编译uboot

通过脚本编译uboot源码

$ ./build.sh

三 SD卡启动盘制作

3.1 bin文件制作

烧写工具默认从 0 扇区开始烧写,这里我们自己在 uboot 之前放一个 512 字节的空镜像

a. 将资料中“u-boot 镜像”中的 u-boot-fs4412.bin 拷贝到工作目录下

b. 在终端输入如下命令,制作一个 512 字节的空镜像

$ sudo dd if=/dev/zero of=zero.bin count=1

显示如下信息,则表示制作成功

c. 执行如下命令,将 uboot 追加到 zero.bin 之后生成 sd-u-boot-fs4412.bin

$ cat zero.bin u-boot-fs4412.bin > sd-u-boot-fs4412.bin

d. 再执行如下命令,制作一个 1M 的空镜像(用于擦除 SD 卡中原有的数据)

$ sudo dd if=/dev/zero of=clear.bin count=2048

3.2 烧写bin文件到SD卡

我使用的烧录工具是图形化的Etcher

下载Etcher工具,解压得到Appimage文件,双击执行

a. 烧写擦除镜像(clear.bin)

选择Etcher界面中的Flash from file,选择好要烧写的clear.bin

如果选择时工作目录下看不到bin文件,可以将右下角的格式筛选改为ALL

选择好后会提示一个警告信息,选择Continue继续

然后点击Select target选择要烧录的设备

选择好要烧写的SD卡,点击Select继续,注意不要选错

写卡千万条,安全第一条,选卡不规范,数据两行泪

点击Flash!开始烧写SD卡!

因为 clear.bin 为空镜像,所以写入后 SD 卡中的前 2048 个扇区中的数据被擦除

b. 烧写sd-u-boot-fs4412.bin到SD卡

重复烧写clear.bin的步骤将sd-u-boot-fs4412.bin到SD卡

3.3 测试uboot

将 SD 卡插入开发板的卡槽,调整拨码开关为 SD 卡启动,查看 uboot 是否能正常启动

注:uboot 正常启动后 LED2 灯会点亮且终端上也会打印 uboot 相关的信息

四 网卡移植

以上步骤完成后,uboot测试的点灯和uart功能正常,也可以通过终端输入命令,此时的uboot还不能使用ping、tftp等命令,原因在于 命令都是操作网络的,而uboot源码中网卡的相关配置与我们当前的板子不匹配,所以 我们还要对网卡进行移植

4.1 修改网络初始化代码

$ vi board/samsung/fs4412/fs4412.c

struct exynos4_gpio_part2 *gpio2;

后添加如下内容

#ifdef CONFIG_DRIVER_DM9000#define EXYNOS4412_SROMC_BASE 0X12570000#define DM9000_Tacs(0x1) #define DM9000_Tcos(0x1) #define DM9000_Tacc(0x5) #define DM9000_Tcoh(0x1) #define DM9000_Tah(0xC) #define DM9000_Tacp(0x9) #define DM9000_PMC(0x1) struct exynos_sromc {unsigned int bw;unsigned int bc[6];};void exynos_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf){unsigned int tmp;struct exynos_sromc *srom = (struct exynos_sromc *)(EXYNOS4412_SROMC_BASE);/* Configure SMC_BW register to handle proper SROMC bank */tmp = srom->bw;tmp &= ~(0xF << (srom_bank * 4));tmp |= srom_bw_conf;srom->bw = tmp;/* Configure SMC_BC register */srom->bc[srom_bank] = srom_bc_conf;}static void dm9000aep_pre_init(void){unsigned int tmp;unsigned char smc_bank_num = 1;unsigned intsmc_bw_conf=0;unsigned intsmc_bc_conf=0;/* gpio configuration */writel(0x00220020, 0x11000000 + 0x120);writel(0x00002222, 0x11000000 + 0x140);/* 16 Bit bus width */writel(0x22222222, 0x11000000 + 0x180);writel(0x0000FFFF, 0x11000000 + 0x188);writel(0x22222222, 0x11000000 + 0x1C0);writel(0x0000FFFF, 0x11000000 + 0x1C8);writel(0x22222222, 0x11000000 + 0x1E0);writel(0x0000FFFF, 0x11000000 + 0x1E8); smc_bw_conf &= ~(0xf<<4);smc_bw_conf |= (1<<7) | (1<<6) | (1<<5) | (1<<4);smc_bc_conf = ((DM9000_Tacs << 28)| (DM9000_Tcos << 24)| (DM9000_Tacc << 16)| (DM9000_Tcoh << 12)| (DM9000_Tah << 8)| (DM9000_Tacp << 4)| (DM9000_PMC));exynos_config_sromc(smc_bank_num,smc_bw_conf,smc_bc_conf);}#endif

gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);

后添加如下内容

#ifdef CONFIG_DRIVER_DM9000dm9000aep_pre_init();#endif

在文件末尾添加如下内容,然后保存退出

#ifdef CONFIG_CMD_NETint board_eth_init(bd_t *bis){int rc = 0;#ifdef CONFIG_DRIVER_DM9000rc = dm9000_initialize(bis); #endif return rc; } #endif

4.2 修改网络配置代码

$ vi include/configs/fs4412.h

#undef CONFIG_CMD_PING

修改为

#define CONFIG_CMD_PING

再将

#undef CONFIG_CMD_NET

修改为

#define CONFIG_CMD_NET

在文件末尾

#endif/* __CONFIG_H */

前添加如下内容,然后保存退出

#ifdef CONFIG_CMD_NET#define CONFIG_NET_MULTI#define CONFIG_DRIVER_DM90001#define CONFIG_DM9000_BASE0x05000000#define DM9000_IOCONFIG_DM9000_BASE#define DM9000_DATA(CONFIG_DM9000_BASE + 4)#define CONFIG_DM9000_USE_16BIT#define CONFIG_DM9000_NO_SROM1#define CONFIG_ETHADDR11:22:33:44:55:66#define CONFIG_IPADDR192.168.9.200#define CONFIG_SERVERIP192.168.9.120#define CONFIG_GATEWAYIP192.168.9.1#define CONFIG_NETMASK255.255.255.0#endif

4.3 编译与测试uboot

通过脚本编译uboot源码

$ ./build.sh

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动, 然后上电查看现象;设置好相关的环境变量,使用网线连接开发板与开发主机,使用 ping命令连接ubuntu,若显示“host xxx.xxx.xxx.xxx is alive”则表示网卡移植成功

五 EMMC移植

因为uboot源码中对EMMC的配置与我们的板子不匹配,这里还需要对EMMC相关的代码进行修改和配置

5.1 修改EMMC初始化代码

将资料中“移植相关文件”下的movi.c拷贝到uboot源码的arch/arm/cpu/armv7/exynos/ 目录下

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi arch/arm/cpu/armv7/exynos/Makefile

COBJS+= clock.o power.o soc.o system.o pinmux.o

修改为如下内容,然后保存退出

COBJS+= clock.o power.o soc.o system.o pinmux.o movi.o

修改板级文件

$ vi board/samsung/fs4412/fs4412.c

#include <asm/arch/mmc.h>

后添加如下内容

#include <asm/arch/clk.h>#include "origen_setup.h"

#ifdef CONFIG_GENERIC_MMC

后添加如下内容

u32 sclk_mmc4; /*clock source for emmc controller*/#define __REGMY(x) (*((volatile u32 *)(x)))#define CLK_SRC_FSYS __REGMY(EXYNOS4_CLOCK_BASE + CLK_SRC_FSYS_OFFSET)#define CLK_DIV_FSYS3 __REGMY(EXYNOS4_CLOCK_BASE + CLK_DIV_FSYS3_OFFSET)int emmc_init(){u32 tmp;u32 clock;u32 i;/* setup_hsmmc_clock *//* MMC4 clock src = SCLKMPLL */tmp = CLK_SRC_FSYS & ~(0x000f0000);CLK_SRC_FSYS = tmp | 0x00060000;/* MMC4 clock div */tmp = CLK_DIV_FSYS3 & ~(0x0000ff0f);clock = get_pll_clk(MPLL)/1000000;for(i=0 ; i<=0xf; i++) {sclk_mmc4=(clock/(i+1));if(sclk_mmc4 <= 160) //200{CLK_DIV_FSYS3 = tmp | (i<<0);break;}}emmcdbg("[mjdbg] sclk_mmc4:%d MHZ; mmc_ratio: %d\n",sclk_mmc4,i);sclk_mmc4 *= 1000000;/** MMC4 EMMC GPIO CONFIG** GPK0[0]SD_4_CLK* GPK0[1]SD_4_CMD* GPK0[2]SD_4_CDn* GPK0[3:6]SD_4_DATA[0:3]*/writel(readl(0x11000048)&~(0xf),0x11000048); //SD_4_CLK/SD_4_CMD pull-down enablewritel(readl(0x11000040)&~(0xff),0x11000040);//cdn set to be outputwritel(readl(0x11000048)&~(3<<4),0x11000048); //cdn pull-down disablewritel(readl(0x11000044)&~(1<<2),0x11000044); //cdn output 0 to shutdown the emmc powerwritel(readl(0x11000040)&~(0xf<<8)|(1<<8),0x11000040);//cdn set to be outputudelay(100*1000);writel(readl(0x11000044)|(1<<2),0x11000044); //cdn output 1writel(0x03333133, 0x11000040);writel(0x00003FF0, 0x11000048);writel(0x00002AAA, 0x1100004C);#ifdef CONFIG_EMMC_8Bitwritel(0x04444000, 0x11000060);writel(0x00003FC0, 0x11000068);writel(0x00002AAA, 0x1100006C);#endif#ifdef USE_MMC4smdk_s5p_mshc_init();#endif }

board_mmc_init函数中的内容修改为(之前的内容删除即可)如下内容

int board_mmc_init(bd_t *bis){int i, err;#ifdef CONFIG_EMMCerr = emmc_init();#endifreturn err;}

在文件的最末尾添加如下内容,然后保存退出

#ifdef CONFIG_BOARD_LATE_INIT#include <movi.h>int chk_bootdev(void)//mj for boot device check{char run_cmd[100];struct mmc *mmc;int boot_dev = 0;int cmp_off = 0x10;ulong start_blk, blkcnt;mmc = find_mmc_device(0);if (mmc == NULL){printf("There is no eMMC card, Booting device is SD card\n");boot_dev = 1;return boot_dev;}start_blk = (24*1024/MOVI_BLKSIZE);blkcnt = 0x10;sprintf(run_cmd,"emmc open 0");run_command(run_cmd, 0);sprintf(run_cmd,"mmc read 0 %lx %lx %lx",CFG_PHY_KERNEL_BASE,start_blk,blkcnt);run_command(run_cmd, 0);/* switch mmc to normal paritition */sprintf(run_cmd,"emmc close 0");run_command(run_cmd, 0);return 0;}int board_late_init (void){int boot_dev =0 ;char boot_cmd[100];boot_dev = chk_bootdev();if(!boot_dev){printf("\n\nChecking Boot Mode ... EMMC4.41\n");}return 0;}#endif

5.2 添加EMMC命令

将资料中“移植相关文件”下的cmd_movi.ccmd_mmc.ccmd_mmc_fdisk.c拷贝到uboot 源码的common/目录下

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi common/Makefile

COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o

后添加如下内容,然后保存退出

COBJS-$(CONFIG_CMD_MMC) += cmd_mmc_fdisk.oCOBJS-$(CONFIG_CMD_MOVINAND) += cmd_movi.o

将资料中“移植相关文件”下的mmc.hmovi.hs5p_mshc.h拷贝到uboot源码的include/ 目录下

将资料中“移植相关文件”下的mmc.cs5p_mshc.c拷贝到uboot源码的drivers/mmc/ 目录下

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi drivers/mmc/Makefile

COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o

后添加如下内容,然后保存退出

COBJS-$(CONFIG_S5P_MSHC) += s5p_mshc.o

5.3 修改EMMC配置代码

$ vi include/configs/fs4412.h

在文件的末尾

#endif/* __CONFIG_H */

前添加如下内容,然后保存退出

#define CONFIG_EVT11 /* EVT1 */#ifdef CONFIG_EVT1#define CONFIG_EMMC44_CH4 //eMMC44_CH4 (OMPIN[5:1] = 4)#ifdef CONFIG_SDMMC_CH2#define CONFIG_S3C_HSMMC#undef DEBUG_S3C_HSMMC#define USE_MMC2 #endif#ifdef CONFIG_EMMC44_CH4#define CONFIG_S5P_MSHC#define CONFIG_EMMC 1#define USE_MMC4 /* #define CONFIG_EMMC_8Bit */#define CONFIG_EMMC_EMERGENCY/*#define emmcdbg(fmt,args...) printf(fmt ,##args) */#define emmcdbg(fmt,args...)#endif#endif /*end CONFIG_EVT1*/#define CONFIG_CMD_MOVINAND#define CONFIG_CLK_1000_400_200#define CFG_PHY_UBOOT_BASECONFIG_SYS_SDRAM_BASE + 0x3e00000#define CFG_PHY_KERNEL_BASECONFIG_SYS_SDRAM_BASE + 0x8000#define BOOT_MMCSD0x3#define BOOT_EMMC430x6#define BOOT_EMMC441 0x7#define CONFIG_BOARD_LATE_INIT

5.4编译与测试uboot

通过脚本编译uboot源码

$ ./build.sh

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动, 然后上电查看现象;若显示EMMC的相关信息则表示EMMC移植成功

六 电源管理移植

因为uboot源码中对电源管理芯片的配置与我们的板子不匹配,后续有可能会导致内核 启动卡死,这里还需要对电源管理芯片相关的代码进行修改和配置

6.1 修改电源管理相关代码

将资料中“移植相关文件”下的pmic_s5m8767.c拷贝到uboot源码的drivers/power/pmic/ 目录下

因为添加的新文件也要编译,所以对应的Makefile也要修改

$ vi drivers/power/pmic/Makefile

COBJS-$(CONFIG_POWER_MAX77686) += pmic_max77686.o

后添加如下内容,然后保存退出

COBJS-$(CONFIG_POWER_S5M8767) += pmic_s5m8767.o

将添加的函数在头文件中声明

$ vi include/power/pmic.h

int pmic_set_output(struct pmic *p, u32 reg, int ldo, int on);

后添加如下内容,然后保存退出

void pmic_s5m8767_init(void);

修改配置文件

$ vi include/configs/fs4412.h

在文件末尾

#endif/* __CONFIG_H */

前添加如下内容,然后保存退出

#define CONFIG_POWER_S5M8767

修改板级文件

$ vi board/samsung/fs4412/fs4412.c

board_init函数中

#ifdef CONFIG_DRIVER_DM9000dm9000aep_pre_init();#endif

后添加如下内容,然后保存退出

#ifdef CONFIG_POWER_S5M8767pmic_s5m8767_init();#endif

注释原有的代码

$ vi drivers/power/Makefile

COBJS-$(CONFIG_POWER) += power_core.o

修改为(即注释掉)

#COBJS-$(CONFIG_POWER) += power_core.o

修改架构文件

$ vi arch/arm/cpu/armv7/s5p-common/cpu_info.c

#include <asm/arch/clk.h>

后添加如下内容,然后保存退出

#include <power/pmic.h>

6.2 编译与测试uboot

通过脚本编译uboot源码

$ ./build.sh

参照之前的实验将生成的u-boot-fs4412.bin烧写到SD卡中,开发板选择SD卡启动,然后上电查看现象

至此,uboot移植完成

(B) Linux内核移植

一 Linux源码下载(linux-3.14.tar.xz)

https://mirrors./pub/linux/kernel/v3.x/

拷贝内核源码包到 ubuntu 的家目录下,解压并进入其顶层目录

$ tar xvf linux-3.14.tar.xz$ cd linux-3.14

二 平台配置

1. 平台配置

1.1 指定编译器

源码并不知道我们的处理器架构及交叉编译工具是什么,我们自己在 Makefile 中指定

$ vi Makefile

ARCH ?= $(SUBARCH)CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)

修改为以下内容(注意后边不要有多余空格),然后保存退出

ARCH ?= armCROSS_COMPILE ?= arm-none-linux-gnueabi-

1.2 指定使用的处理器

$ make exynos_defconfig

显示如下信息表示配置成功

2. uart配置

2.1 配置工具

$ make menuconfig

若出现图形库错误,执行如下命令安装,然后重新执行 make menuconfig 即可

$ sudo apt-get install libncurses5-dev

2.2 修改输出串口

将‘System Type’菜单下的‘S3C UART…’修改为 2(即使用 UART2)

System Type --->(2) S3C UART to use for low-level messages

设置完成后通过方向键选择‘Save’保存即可,然后选择‘Exit’退出该配置界面

三 网卡驱动移植

1. 选配网卡

1、 在内核源码的顶层目录下执行如下命令,修改内核配置

$ make menuconfig

给内核选配DM9000网卡驱动,然后选择“Save”保存

Device Drivers --->[*] Network device support --->[*] Ethernet driver support ---><*> DM9000 support

2. 配置NFS

因为内核要使用 NFS 去挂载根文件系统,而 NFS 是基于 TCP 协议实现的,所以这里需要选配 TCP 相关的网络协议(部分功能默认已经选配),然后选择“Save”保存

[*] Networking support --->Networking options ---><*> Packet socket<*> Unix domain sockets[*] TCP/IP networking[*] IP: kernel level autoconfiguration

因为内核要使用 NFS 去挂载根文件系统,所以需要给内核选配 NFS 客户端及相关功能

File systems --->[*] Network File Systems ---><*> NFS client support<*> NFS client support for NFS version 3 (NEW)[*] NFS client support for the NFSv3 ACL protocol extension[*] Root file system on NFS

设置完成后通过方向键选择‘Save’保存即可,然后选择‘Exit’退出该配置界面

3. 编译内核

$ make uImage

第一次在 ubuntu 上编译 Linux 内核会提示缺少一个mkimage 命令,该命令可在 uboot 源码中 u-boot-.01/tools/目录下获取(必须是编译后的 uboot),将该命令拷贝到 ubuntu 的/usr/bin 目录下即可正确编译内核

$ sudo cp u-boot-.01/tools/mkimage /usr/bin/

给该命令添加可执行权限

$ sudo chmod 777 /usr/bin/mkimage

完成后回到内核的顶层目录下重新编译内核即可

( C ) 设备树移植

内核源码中并没有 fs4412 平台的设备树文件,这里我们从源码支持的平台中找一个硬件与我们最类似的,在其基础上进行修改

一 平台配置

这里我参考的是 samsung 公司的 origen拷贝 origen 的设备树并将其重命名

$ cp arch/arm/boot/dts/exynos4412-origen.dts arch/arm/boot/dts/exynos4412-fs4412.dts

因为添加的设备树文件也要编译,所以对应的 Makefile 也要修改

$ vi arch/arm/boot/dts/Makefile

exynos4412-origen.dtb \

后添加如下内容,然后保存退出

exynos4412-fs4412.dtb \

回到源码的顶层目录下编译设备树

$ make dtbs

二 修改配置

1 修改网卡配置

在设备树中添加网卡的硬件信息

$ vi arch/arm/boot/dts/exynos4412-fs4412.dts

在文件的末尾,最后一个花括号前添加如下内容(即要写在根节点之内)

srom-cs1@5000000 {compatible = "simple-bus";#address-cells = <1>;#size-cells = <1>;reg = <0x5000000 0x1000000>;ranges;ethernet@5000000 {compatible = "davicom,dm9000";reg = <0x5000000 0x2 0x5000004 0x2>;interrupt-parent = <&gpx0>;interrupts = <6 4>;davicom,no-eeprom;mac-address = [00 0a 2d a6 55 a2];};};

2 修改时钟配置

忽略无用的时钟

$ vi drivers/clk/clk.c

static bool clk_ignore_unused;

修改为以下内容,然后保存退出

static bool clk_ignore_unused=true;

3 修改EMMC相关配置

$ vi drivers/mmc/core/mmc.c

if (card->ext_csd.rev > 7) {pr_err("%s: unrecognised EXT_CSD revision %d\n",mmc_hostname(card->host), card->ext_csd.rev);err = -EINVAL;goto out;}

修改为以下内容,然后保存退出

#if 0if (card->ext_csd.rev > 7) {#elseif (card->ext_csd.rev > 8) {#endifpr_err("%s: unrecognised EXT_CSD revision %d\n", mmc_hostname(card->host), card->ext_csd.rev);err = -EINVAL;goto out;}

三 编译与测试

1 编译内核和设备树

$ make uImage$ make dtbs

2 测试内核和设备树

将编译生成的内核和设备树拷贝到 tftp 的工作目录

$ sudo cp arch/arm/boot/uImage /tftpboot$ sudo cp arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/$ sudo chmod 777 /tftpboot/*

重启 tftp 和 nfs 服务器

$ sudo service tftpd-hpa restart$ sudo service nfs-kernel-server restart

重启开发板查看现象,如图所示,此时 Linux 内核已经能通过 NFS 去挂载根文件系统

在终端下执行‘ls’命令我们就能看到根文件系统中的内容

( D ) 根文件系统移植

一 busybox工具

在 busybox 官网下载 busybox 源码(这里我们下载 busybox-1.22.1.tar.bz2)

/downloads/

拷贝 busybox 源码包到 ubuntu 的家目录下,解压并进入其顶层目录

$ tar xvf busybox-1.22.1.tar.bz2$ cd busybox-1.22.1/

二 配置根文件系统

1 进入 busybox 配置界面

与 Linux 内核配置方法一样

$ make menuconfig

2 配置busybox

参考如下信息配置 busybox

Busybox Settings --->Build Options --->[*] Build BusyBox as a static binary (no shared libs)[ ] Build with Large File Support (for accessing files > 2 GB)(arm-none-linux-gnueabi-) Cross Compiler prefix

配置完成后通过方向键选择‘Exit’退出,并保存配置信息

3 编译与安装busybox

编译busybox

$ make

编译完成后在源码的顶层目录下会生成 busybox 文件

安装 busybox

$ make install

安装完成后在源码的顶层目录下会生成_install目录

4 移植根文件

4.1 查看文件

进入到安装目录下查看生成的文件

$ cd _install/$ ls

如下图所示,在安装目录下生成了根文件系统中所需的 shell 命令文件

4.2 拷贝库文件

将交叉编译工具链中的库文件拷贝到_install 目录下

$ cp /home/linux/Linux_4412/toolchain/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/lib/ . -a

这样在安装目录下就有了根文件系统中所需的库文件

4.3 删除库文件中的静态库

$ sudo rm lib/*.a

删除共享库中的符号表(需要在 root 用户下操作)

$ du -mh lib

$ sudo su$ /home/linux/Linux_4412/toolchain/gcc-4.6.4/bin/arm-none-linux-gnueabi-strip lib/*$ exit

4.4 拷贝etc目录

将资料中“移植相关文件”下的etc目录(配置文件)拷贝到当前目录下

4.5 给 etc/init.d/下的 rcS 脚本添加可执行权限

$ chmod +x etc/init.d/rcS

4.6 创建其他目录

$ mkdir dev mnt proc root sys tmp var

如下图所示,至此我们就构建好了自己的根文件系统

4.7 拷贝根文件系统

删除原来的根文件系统

$ sudo rm -rf /opt/4412/rootfs/*

将自己制作的根文件系统拷贝到 NFS 的工作目录下测试

$ sudo cp -rf ./* /opt/4412/rootfs

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。