ARM的uboot引导系统制作和linux的系统移植

前言:

          本文章将详细介绍在一个裸板(ARM板)上移植并配置一个linux系统,其中包含uboot引导系统的制作与移植以及liunx的制作移植。博主用的是三星Exynos4412芯片和FS4412_CoreBoard_V2核心板,具体的其他板子会有差异。

相关资料链接:

链接:https://pan.baidu.com/s/1uv_N-8dQlZli4Bc2xfPbRg 
提取码:xs66

    前期准备:

            由于篇幅原因,将不在详细介绍前期的一些准备工作。但是可以说一下具体有哪一些:1、需要有自己的一块板子。2、需要有一个U盘或者SD卡做一个启动盘,其中下载启动引导系统作为启动盘来提供基本的串口通讯功能。3、需要串口通讯工具(如Xshell、超级终端等)。4、还需要搭建板子和主机之间的tftp通讯(在SD卡可正常引导启动后进行),可参考:(19条消息) arm linux启动tftp服务器,ubuntu下配置TFTP服务器,用以ubuntu下烧写内核到ARM开发板..._weixin_39772352的博客-优快云博客OK!到这一步,估计你已经准备的差不多了...^_^

一、系统引导(bootloader):

1.制作uboot.bin

到uboot.bin官网下载对板子和芯片的uboot.bin制作环境压缩包(Index of /pub/u-boot/)

修改makefile CROSS_COMPILE ?=arm-linux-(设置编译器为arm架构的)

用make distclean 打扫之前的编译环境

在borads.cfg找到对应板子,如qong,用make qong_config 制作配置(可以来两次)

make开始编译 制作uboot.bin

2.移动uboot.bin到板子

(uboot.bin 之前要链接 bl1和bl2 (cat E4412_N.bl1.SCP2G.bin bl2.bin all00_padding.bin u-  boot.bin tzsw_SMDK4412_SCP_2GB.bin > u.bin))

复制到 tptf共享文件夹 cp u.bin /home/xs/tftp/(该步骤在网盘文件中有脚本可以执行)

启动板子 输入 tftp 41000000 u.bin

保存 movi write u-boot 41000000

异常处理:

1、灯闪烁:某种中断导致,直接切断电源模块的接收中断功能。
在arch->arm->cpu->对应cpu下的start.s    set the cpu to SVC32 mode后加
/*设置ONO*/
ldr r1,=0x11000c00
ldr r2,[r1]
bic r2,r2,#0x00000F00
orr r2,r2,#0x00000100
str r2,[r1]
ldr r1,=0x11000c04
ldr r2,[r1]
bic r2,r2,#0x00000004
orr r2,r2,#0x00000004
str r2,[r1]
/*ONO end*/
2、串口通讯不成功:参数设置不对,没有确定输入时钟频率,故波特率不确定。
在对应板子的lowlevel_init.s中:
在 1:
/* for UART */
bl uart_asm_init
/*屏蔽这一行*/
@ bl tzpc_init
在uart_asm_init:
/*xs 修改*/
ldr	r0, =EXYNOS4_CLOCK_BASE
/* UART[0:4] */
ldr	r1, =CLK_SRC_PERIL0_VAL
ldr	r2, =CLK_SRC_PERIL0_OFFSET
str	r1, [r0, r2]
/* CLK_DIV_PERIL0: UART Clock Divisors */
ldr	r1, =CLK_DIV_PERIL0_VAL
ldr	r2, =CLK_DIV_PERIL0_OFFSET
str	r1, [r0, r2]
/*uart时钟修改结束*/
备注:如果打算使用 tftp传输文件 那么就需要将网络功能打开 具体步骤如下:
1、增加命令:
fs4412.h中修改(打开宏开关)  板子名的.h文件
{
#define  CONFIG_CMD_PING
#define  CONFIG_CMD_NET
}
2、增加网络设备初始化
origen.c中增加
{
	#ifdef CONFIG_DRIVER_DM9000
	int board_eth_init(bd_t *bis)
	{
		return dm9000_initialize(bis);
	}
	#endif
}
fs4412.h中增加
{
	#ifdef  CONFIG_CMD_NET
	#define CONFIG_DRIVER_DM9000  1
	#define CONFIG_DM9000_BASE    0x05000000     /*DM9000基地址*/
	#define DM9000_IO      	      CONFIG_DM9000_BASE
	#define DM9000_DATA    	     (CONFIG_DM9000_BASE + 4)

	#define CONFIG_ETHADDR 	        11:22:33:44:55:66 /*MAC   */
	#define CONFIG_IPADDR  		    192.168.12.251   /*板子ip*/
	#define CONFIG_SERVERIP        	192.168.12.147  /*主机ip*/
	#define CONFIG_GATEWAYIP      	192.168.12.1   /*网段  */
	#define CONFIG_NETMASK 		    255.255.255.0 /*掩码  */
	#endif
}
3、增加SROM设置
在fs4412/origen.c 增加:
   在board_init中增加:
{
	#ifdef CONFIG_DRIVER_DM9000
        dm9000aep_pre_init();
	#endif
}

在fs4412/origen.c 增加:
{
	#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];
	};

/*
* s5p_config_sromc() - select the proper SROMC Bank and configure the
* band width control and bank control registers
* srom_bank    - SROM
* srom_bw_conf  - SMC Band witdh reg configuration value
* srom_bc_conf  - SMC Bank Control reg configuration value
*/
	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 int     smc_bw_conf=0;
		unsigned int     smc_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
}

3.启动uboot

设置uboot启动参数(注意IP地址和其他参数的更改 我这里192.168.1.12是板子ip)

set bootargs root=/dev/ram rw console=ttySAC2,115200 clk_ignore_unused init=/linuxrc ip=192.168.1.12
save

拨动拨码开关 上电 启动

二、内核移植(kernel)

uImage编译:

到linux官网下载制作kernel的压缩包(https://www.kernel.org/)
tar -xvf 压缩包名
修改makefile CROSS_COMPILE ?=arm-linux-(设置编译器为arm架构的)
看芯片是否支持,arch/arm(架构名)/configs/ -------->exynos_defconfig(三星的一个芯片配置文件)
如果不支持就换高版本的linux,或者找厂家
make exynos_defconfig(对应配置文件--可修改)  :注意 这是对配置文件的加载写入,不过一般都不采取这种方式 ,一般用下一行方法
make menuconfig  可视化窗口配置配置文件 需要啥就选择(开DM9000的配置 在Device Drivers → Network device support → Ethernet driver support→ DM9000下)
上面开了DM9000配置文件后 需要在设备树源码文件(arch/arm/boot/dts/对应板子.dts)下挂载:

在 .dts文件下 增加:
#include <dt-bindings/interrupt-controller/irq.h>

在结尾增加:(注意 包含在大框架内 也就是最后还要有一个花括号)
     /*新增网络*/
     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 IRQ_TYPE_LEVEL_HIGH>;
			davicom,no-eeprom;
		};
	};
tb编译:

确认板子是否匹配 arch/arm/boot/dts/  没有 就找芯片相同的借鉴
修改Makefile  增加 你要编译的板子 .dtb  没有就借鉴 有就不管了

make dtbs 生成 .dtb文件 

将这个文件 和uImage文件一起拷贝到tftp文件夹

2、根文件系统(rootfs)

网络文件系统 nfs:

ubuntu主机端:

安装:sudo apt-get install nfs-kernel-server

 准备目录:在家目录下的任意目录创建一个rootfs文件夹 可以是空的(用于放我们自己的根文件系统) 或者是解   压的 rootfs.tgz

配置nfs:

sudo vi etc/exports

加一行 rootfs文件夹的路径 *   (rw,sync,no_subtree_check,no_root_squash)

重启生效:

sudo /etc/init.d/nfs-kernel-server restart

板子客户端:

需要重新生成一个uImage文件;
 → Networking support → Networking options→ IP: kernel level autoconfiguration :先把自动IP打开

make menuconfig 找到nfs :

File systems → Network File Systems → NFS client support 和 Root file system on NFS(没开自动IP没有该选项) 选择需要

板子 uboot 需要更改为:

 set bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;bootm 41000000 - 42000000
 set bootargs root=/dev/nfs nfsroot=192.168.1.11(你的主机址):/home/hqyj/hq/xs/sys/rootfs(你的rootfs路径),v3 rw console=ttySAC2,115200 clk_ignore_unused init=/linuxrc ip=192.168.1.12(板子的地址)
 save
己制作一个rootfs:

下载busybox压缩包(https://busybox.net/)

在家目录下的任意目录解压

在解压的目录下 make menuconfig 找到:Busybox Settings → Build Options → Build BusyBox as a static binary和(arm-linux-) Cross Compiler prefix   (括号内是要填的交叉编译环境)

make 或者 make -j8
make install (你自己制作的rootfs就在 _install下产生了)
在_install 目录下创建 /proc /tmp /sys /dev 文件夹
然后 就需要lib文件(复制到_install下) 一般移植对应框架的 gun 下的lib 用 echo $PATH查找路径为/home/hqyj/Downloads/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi
最后 需要etc文件(复制到_install下) 这个包含启动和配置文件 inittab 文件是启动时调用的文件(可以在这里添加自启动软件) profile 是可以更改一些用户信息的
最后将自己_install下的所有文件移动到自己的rootfs 下 就可以了

rootfs相关文件:

rcS文件
#!/bin/sh                                      
#This is the first script called by init process
/bin/mount -a ----》关联文件系统                  
mkdir /dev/pts                                  
mount -t devpts devpts /dev/pts                 
echo /sbin/mdev>/proc/sys/kernel/hotplug        
mdev -s  
inittab文件
#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS

# /bin/sh invocations on selected ttys

# Start an "askfirst" shell on the console (whatever that may be)

::respawn:-/bin/sh

# Stuff to do when restarting the init process

::restart:/sbin/init

# Stuff to do before rebooting

::ctrlaltdel:/sbin/reboot
profile文件
#!/bin/sh
export HOSTNAME=xs
export USER=root
export HOME=root
#export PS1="\[\u@\h \W\]\$ "
#cd root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值