s5p6818/fs4418系统移植之uboot的移植

  • Post author:
  • Post category:其他


/*****************
	uboot移植
******************/		
【1】获取u-boot源码
	1. u-boot官方网站
		https://ftp.denx.de/pub/u-boot/
	2. 开发板厂家 
	3. 芯片厂家
	4. 主管领导(推荐)
	第1种和第2,3,4种有何区别?
	芯片厂家没有将芯片的uboot支持的源码开源
	到u-boot官方源码中,
	uboot官方源码不支持此处理器。
	
	S5P6818芯片三星没有将支持此处理器的
	源码开源到uboot官方,uboot官方获取的
	uboot源码不支持S5P6818芯片。
	
	此课程使用的fs6818的uboot源码:u-boot-2014.07-netok.tar.bz2

【2】uboot版本选择
	* 1. 芯片厂家提供哪个版本就直接用哪个版本
	2. 不选最新  --》 不稳定,资料较少
	3. 不选太旧  --》 不支持硬件平台
	4. 不选择测试版,选择稳定版
		后缀有rc为测试版
【3】移植的准备工作
	根据处理器获取硬件相关的信息。
	
	cpu:Cortex-A53 
	arch:ARM
	SOC:S5P6818 
	vendor:samsung
	board:S5P6818 ---》fs6818开发板
【4】移植uboot源码	
1. 准备uboot源码	
	1》 拷贝uboot源码到ubuntu中。
	
	2》 解压缩uboot源码
		tar -vxf u-boot-2014.07-netok.tar.bz2

	3》 进入uboot源码目录 
		cd u-boot-2014.07
		
		不要将源码放到共享文件夹中,
		源码不要在windows下边去解压缩。
		windows不支持软连接文件。
2. 分析uboot源码的目录结构 
	平台相关:跟硬件相关的代码
	arch :架构相关代码
	board:板子相关代码	
	samsung公司将arch和borad目录下很多跟自己硬件无关的代码全部删除
	uboot源码的配置编译和管理使用Makefile工具。
3. 配置和编译uboot源码:
	1》 make help  : 查看make的帮助信息
	清除目标:
	  clean		 
	  mrproper	
	  distclean	  

	编译uboot源码:
		all		 

	Execute "make" or "make all" to build all targets marked with [*] 
	For further info see the ./README file
	更多的详细的信息查看README。
        2》读README 
	 254 For all supported boards there are ready-to-use default
	 255 configurations available; just type "make <board_name>_config".
	 256 
	 257 Example: For a TQM823L module type:
	 258 
	 259     cd u-boot
	 260     make TQM823L_config

make <board_name>_config  作用?
	由于uboot源码支持多种架构和开发板,应该配置uboot支持
	当前自己使用的开发板,目的是编译uboot源码时,
	只编译跟自己硬件平台相关的代码。

	3》uboot源码详细的配置编译过程
		1> 修改Makefile配置交叉编译工具链
		打开uboot源码顶层目录的Makefile,修改以下内容:
		 198 ifeq ($(HOSTARCH),$(ARCH))
		 199 CROSS_COMPILE ?=                
		 200 endif
		修改为:
		198 ifeq (arm,arm)
		199 CROSS_COMPILE ?= arm-none-linux-gnueabi-
		200 endif

		2> 清除中断文件
			make distclean 
			
			切记:make distclean只在第一次编译是执行一次。
		
		3> 配置uboot源码支持fs6818开发板
			make fs6818_config
			
			打印以下信息表示配置成功:
			Configuring for fs6818 board...

		4> 编译uboot源码,生成uboot的镜像(可执行文件)
			make/make all
			
		打印以下信息表示编译成功,生成ubootpak.bin
		  LD      u-boot
		  OBJCOPY u-boot.srec
		  OBJCOPY u-boot.bin
		./tools/mk6818 ubootpak.bin nsih.txt 2ndboot u-boot.bin
		NSIH : 188 line processed.
		NSIH : 512 bytes generated.
		Generate destination file: ubootpak.bin



分析make fs6818_config命令的执行过程详解
		需要具备能力:看到Makefile shell脚本
1. 打开uboot源码顶层目录的Makefile文件,
	搜索fs6818_config,搜索发现没有fs6818_config目标。
	
	%:模式匹配符
	
	搜索_config,找到以下信息:
		
	 467 %_config:: outputmakefile                                     
	 468     @$(MKCONFIG) -A $(@:_config=)
	 469     @cp net/x6818-eth.mk net/eth.o
	
	去掉@$(MKCONFIG) -A $(@:_config=)前边的@符号,
	将命令回显到终端。
	/home/hqyj/20021/porting/u-boot-2014.07/mkconfig -A fs6818
	
	$(@:_config=):截取fs6818_config中的fs6818字符串
		
2. 使用file命令查看mkconfig文件的属性
	file mkconfig  : shell脚本文件
		
3. 打开uboot源码顶层目录的mkconfig脚本文件		
 24 if [ \( $# -eq 2 \) -a \( "$1" = "-A" \) ] ; then
 25     # Automatic mode
 26     line=`awk '($0 !~ /^#/ && $7 ~ /^'"$2"'$/) { print $1, $2, $3, $4, $5, $6, $7, $8 }' $srctree/boards.cfg`
 27     if [ -z "$line" ] ; then
 28         echo "make: *** No rule to make target \`$2_config'.  Stop." >&2
 29         exit 1
 30     fi
 31 
 32     set ${line}
 33     # add default board name if needed
 34     [ $# = 3 ] && set ${line} ${1}
 35 fi         	
	解析:
	$# : 参数的个数
	$1 : 第一个参数
	$2 : 第二个参数
	-eq :相等
	-a :并且	
	$0 !~ /^#/ : 不是以#开头	
	$7 ~ /^'"$2"'$/ :$7和$2相等
	
	打开uboot源码顶层目录的boards.cfg 
	
	line=Active arm slsiap s5p6818 s5p6818 fs6818 fs6818 -  
	
	set ${line} :重新设置脚本文件传递的参数
	之前:
	mkconfig -A fs6818 
			 $1    $2
	执行set ${line}之后:
	mkconfig Active arm slsiap s5p6818 s5p6818 fs6818 fs6818 - 
				$1   $2  $3       $4      $5      $6    $7   $8
51 CONFIG_NAME="${7%_config}"
 52 
 53 [ "${BOARD_NAME}" ] || BOARD_NAME="${7%_config}"
 54 
 55 arch="$2"                                                  
 56 cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $1}'`
 57 spl_cpu=`echo $3 | awk 'BEGIN {FS = ":"} ; {print $2}'`
	解析: 
	CONFIG_NAME=fs6818 
	arch=arm
	cpu=slsiap
 63 [ "$6" != "-" ] && board="$6"
 64 [ "$5" != "-" ] && vendor="$5"                               
 65 [ "$4" != "-" ] && soc="$4"
	board=fa6818
	vendor=s5p6818
	SOC=S5P6818
 96 if [ "$options" ] ; then
 97     echo "Configuring for ${BOARD_NAME} - Board: ${CONFIG_NAME}, Options: ${
 98 else  # 配置成功打印以下内容
 99     echo "Configuring for ${BOARD_NAME} board..."
100 fi

	# 创建架构头文件
	102 #
	103 # Create link to architecture specific headers
	104 #
	105 if [ -n "$KBUILD_SRC" ] ; then
	106     mkdir -p ${objtree}/include
	107     LNPREFIX=${srctree}/arch/${arch}/include/asm/
	108     cd ${objtree}/include
	109     mkdir -p asm
	110 else
	111     cd arch/${arch}/include
	112 fi
	113 
	114 rm -f asm/arch
	115 
	116 if [ "${soc}" ] ; then
	117     ln -s ${LNPREFIX}arch-${soc} asm/arch
	118 elif [ "${cpu}" ] ; then
	119     ln -s ${LNPREFIX}arch-${cpu} asm/arch
	120 fi
	121              
	122 if [ -z "$KBUILD_SRC" ] ; then
	123     cd ${srctree}/include
	124 fi

	# 创建Make工具需要使用的配置头文件
	126 #
	127 # Create include file for Make
	128 #
	129 ( echo "ARCH   = ${arch}"
	130     if [ ! -z "$spl_cpu" ] ; then
	131     echo 'ifeq ($(CONFIG_SPL_BUILD),y)'
	132     echo "CPU    = ${spl_cpu}"
	133     echo "else"
	134     echo "CPU    = ${cpu}"
	135     echo "endif"
	136     else
	137     echo "CPU    = ${cpu}"
	138     fi
	139     echo "BOARD  = ${board}"
	140 
	141     [ "${vendor}" ] && echo "VENDOR = ${vendor}"
	142     [ "${soc}"    ] && echo "SOC    = ${soc}"
	143     exit 0 ) > config.mk
	打开include目录下的config.mk文件,有以下信息:
	  1 ARCH   = arm                                                               
	  2 CPU    = slsiap
	  3 BOARD  = fs6818
	  4 VENDOR = s5p6818
	  5 SOC    = s5p6818

	创建板子指定的头文件
	152 #
	153 # Create board specific header file
	154 #
	155 if [ "$APPEND" = "yes" ]    # Append to existing config file
	156 then
	157     echo >> config.h
	158 else
	159     > config.h      # Create new config file
	160 fi
	161 echo "/* Automatically generated - do not edit */" >>config.h
	162 
	163 for i in ${TARGETS} ; do
	164     i="`echo ${i} | sed '/=/ {s/=/  /;q; } ; { s/$/ 1/; }'`"
	165     echo "#define CONFIG_${i}" >>config.h ;
	166 done  
	168 echo "#define CONFIG_SYS_ARCH  \"${arch}\""  >> config.h
	169 echo "#define CONFIG_SYS_CPU   \"${cpu}\""   >> config.h
	170 echo "#define CONFIG_SYS_BOARD \"${board}\"" >> config.h                                     
	171 
	172 [ "${vendor}" ] && echo "#define CONFIG_SYS_VENDOR \"${vendor}\"" >> config.h
	173 
	174 [ "${soc}"    ] && echo "#define CONFIG_SYS_SOC    \"${soc}\""    >> config.h
	175 
	176 [ "${board}"  ] && echo "#define CONFIG_BOARDDIR board/$BOARDDIR" >> config.h
	177 cat << EOF >> config.h
	178 #include <config_cmd_defaults.h>
	179 #include <config_defaults.h>
	180 #include <configs/${CONFIG_NAME}.h>
	181 #include <asm/config.h>
	182 #include <config_fallbacks.h>
	183 #include <config_uncmd_spl.h>
	184 EOF
	185 
	打开include目录下的config.h文件,有以下信息:
	1 /* Automatically generated - do not edit */
  2 #define CONFIG_SYS_ARCH  "arm"
  3 #define CONFIG_SYS_CPU   "slsiap"
  4 #define CONFIG_SYS_BOARD "fs6818"
  5 #define CONFIG_SYS_VENDOR "s5p6818"
  6 #define CONFIG_SYS_SOC    "s5p6818"
  7 #define CONFIG_BOARDDIR board/s5p6818/fs6818
  8 #include <config_cmd_defaults.h>
  9 #include <config_defaults.h>
 10 #include <configs/fs6818.h>
 11 #include <asm/config.h>
 12 #include <config_fallbacks.h>
 13 #include <config_uncmd_spl.h>   
【8】开发板系统的部署
	
	uboot镜像:ubootpak.bin 
	linux内核镜像:uImage
	根文件系统镜像:ramdisk.img 
	根文件系统:rootfs
	
	ramdisk.img由rootfs打包压缩得到 

	1. 开发阶段系统部署方式 (驱动开发)
	uboot ---》EMMC/SD卡 
	uImage ---》使用tftp下载到内存中
	rootfs ---》使用nfs网络文件系统的方式进行挂载
 	
	2. 产品阶段系统部署方式(项目完成) 
	uboot ---》EMMC/SD卡 
	uImage ---》EMMC/SD卡 
	ramdisk.img  ---》EMMC/SD卡 
【开发阶段系统部署方式】 
	内核镜像:系统移植\系统移植资料\镜像\uImage 
	
	1. 启动uboot进入uboot的交互界面
		
	2. 下载内核镜像uImage到内存中
		先将uImage镜像文件拷贝到tftpboot目录下,
		
		tftp 0x48000000 uImage
		
	3. 设置自启动参数bootargs, 重点掌握面试出现概率高。
		uboot环境变量中的bootargs变量是一个自启动参数,
		linux内核启动时,会uboot环境变量的分区读取bootargs变量的值。
		(只需要设置一次)
		
		ubuntu系统是32位:
		setenv bootargs root=/dev/nfs nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.1.222
		saveenv 
		ubuntu系统是16.04 64位:
		setenv bootargs root=/dev/nfs nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs v4,tcp rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.1.222
		
		ubuntu系统是18.04以上 64位:
		setenv bootargs root=/dev/nfs nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs v4,tcp rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.1.222
		
		ubuntu系统是18.04以上版本需要修改ubuntu中的配置文件:
		参考文档:
		https://www.jianshu.com/p/10e3245f15f3?tdsourcetag=s_pctim_aiomsg
		
		root=/dev/nfs:根文件系统的类型是nfs
		nfsroot=192.168.1.250:/home/hqyj/nfs/rootfs:
			根文件系统的路径,改成自己的ubuntu 
			IP地址和根文件系统的路径
			
		rw:对根文件系统具有可读可写的权限
		console=/dev/ttySAC0,115200:
			开发板使用的是串口0,波特率是115200 
			
		init=/linuxrc:内核启动之后执行的1号进程
		ip=192.168.1.222:开发板的IP地址
		
		
		bootargs:就是告诉内核从哪里挂载根文件系统的,
			
	4. 启动linux内核 
		bootm 0x48000000
		
		bootm:用于启动linux内核的命令

	
	5. 总结:根文件系统挂载不成功的原因
		1》检查nfs安装和配置是否正确
		2》重启nfs服务
			sudo service nfs-kernel-server restart
		3》检查bootargs参数设置是否正确	
	
		tftp下载镜像不成功的原因,翻阅前边的笔记。

uboot配置编译流程:

 uboot配置编译流程
	1》配置交叉编译工具链
		CROSS_COMPILE
	2》清除源码的中间文件
		make clean / distclean 
	3》配置源码支持自己的硬件平台
		make  <board_name>_config
		make fs6818_config
	4》编译uboot源码
		make all 

通过ubuntu系统烧写ubootpak.bin到SD卡中

使用sdtool工具:工具在以下目录中:
	系统移植\系统移植资料\工具\sdtool

	1》拷贝sdtool工具到ubuntu中,并切换到sdtool目录下 	
		....
		cd sdtool 
	2》将SD卡插到PC上,并让ubuntu识别SD卡,
		要求:必须使用SD卡读卡器,不可以使用电脑自带的SD卡卡槽
		SD卡被ubuntu识别之前,先在windows下对SD卡进行格式化。
		
		ubuntu识别SD卡步骤:
		虚拟机-》可移动设备-》读卡器的名字-》连接
		
		读卡器或者电脑是USB3.0的接口:
		虚拟机-》设置-》USB控制器-》USB兼容性:--》USB3.0

	3》进入到sdtool目录下
		s5p6818-sdmmc.sh:烧写ubootpak.bin到SD卡中的脚本文件
		ubootpak.bin:自己编译生成的u-boot的镜像 
		
		使用我们自己制作的ubootpak.bin文件替换
		sdtool目录下的ubootpak.bin文件。
	4》烧写ubootpak.bin文件到SD卡中 
		在ubuntu的终端中执行以下命令 
		sudo ./s5p6818-sdmmc.sh /dev/sdb ubootpak.bin 
		/dev/sdb : SD卡在dev目录下的设备文件
		
		执行以上命令出现以下内容,表示制作成功:
		669+1 records in
		670+0 records out
		343040 bytes (343 kB) copied, 0.00605781 s, 56.6 MB/s
		^_^ The image is fused successfully
	5》测试SD卡是否成功烧写uboot的镜像
		1. 开发板断电,
		2. 将SD卡插到开发板的SD卡槽上
		3. 设置开发板的启动方式为SD卡启动:查看拨码开关上边的表格
			拨码开关 
			1   OFF
			2   OFF 
			3   OFF
		4. 开发板上电
		
	注意: 
		1. 格式化SD卡,格式化为Fat32格式 
			在ubuntu中格式化使用fdisk命令。
		2. SD卡上的开关拨到lock位置,
			如果拨到Lock的对立面,SD卡会写保护。

	s5p6818-sdmmc.sh脚本文件分析:
	dd if="${xboot}" of="${dev}" bs=512 seek=1 conv=sync 
	dd:数据烧写命令
	xboot=ubootpak.bin 
	dev=/dev/sdb
	if:输入文件 (input file)
	of:输出文件 (output file)
	bs:大写是512字节
	seek:偏移seek*bs大小空间
	conv=sync:同步

通过windows系统烧写xin_ubootpak.bin到SD卡中


通过windows系统烧写xin_ubootpak.bin到SD卡中
	使用windows下的工具:
	系统移植\系统移植资料\工具\ImageWriter.7z
	解压缩之后,双击打开工具:Win32DiskImager.exe

	1. 首先得到windows版本的ubootpak.bin 
		在ubuntu版本的ubootpak.bin文件前边添加512字节的占位,
		跳过SD的前边512字节的分区表。
		
		dd if=/dev/zero of=512B bs=512 count=1
		chmod 777 512B 
		cat 512B ubootpak.bin > win_ubootpak.bin
		
		拷贝win_ubootpak.bin到windows文件夹中
		
	2. 将SD卡插到PC上,可以使用PC自带的SD卡卡槽
		打开Win32DiskImager.exe,选择SD卡的盘符,
		选择要写到SD卡中的win_ubootpak.bin文件,
		单击write,就可以写入到SD卡中。
		
	3. 测试SD卡是否制作成功。

烧写ubootpak.bin到EMMC(flash)中

烧写ubootpak.bin到EMMC(flash)中
	前提:SD卡启动盘必须制作好,前边已经完成。
		通过SD卡的方式启动uboot,并进入uboot的交互界面。
	
	思路:ubootpak.bin烧写到EMMC中的思路.png
	
	1. 通过SD卡的方式启动uboot,并进入uboot的交互界面。 
	
	2. 使用tftp命令将ubootpak.bin文件烧写到内存中
		先将ubootpak.bin拷贝到tftpboot目录下
		cp ubootpak.bin ~/tftpboot/
		
		tftp 0x41000000 ubootpak.bin 
		将ubootpak.bin烧写到内存的0x41000000地址中

	3. 将内存中的ubootpak.bin使用update_mmc命令烧写到EMMC中
		update_mmc <dev no> <type> <mem> <addr> <length>
			- type :  2ndboot | boot | raw | part
		<dev no>:设备号  EMMC设备号为:2
		<type>:类型 2ndboot 
		<mem>:从内存的哪个地址开始进行数据搬移
		<addr>:搬移到EMMC的起始地址,以字节为单位
		<length>:搬移数据的长度,以字节为单位 
				具体长度要看ubootpak.bin大小

		pri打印环境变量有以下信息:
		flash=mmc,2:ubootpak:2nd:0x200,0x78000;
		flash=mmc,2:2ndboot:2nd:0x200,0x4000;
		
		update_mmc 2 2ndboot 0x41000000 0x200 0x78000
		
	4. 测试是否烧写成功
		1. 开发板断电,
		2. 切换到EMMC的启动方式
			拨码开关 
			1   ON
			2   OFF 
			3   ON
		3. 开发板上电

uboot中mmc命令的使用

uboot中mmc命令的使用
	1》mmc info - display info of the current MMC device
		查看当前mmc设备的信息
	2》mmc read addr blk# cnt
		作用:从MMC中读数据到内存中
		
		addr:内存的起始地址 
		blk#:MMC块设备的编号,一块是512字节
		cnt:个数
		
		从MMC的起始块号为blk的位置读数据到内存的addr为起始地址处,
		读cnt块数据的大小
		
	3》mmc write addr blk# cnt
		作用:从内存中写数据到MMC中
		addr:内存的起始地址 
		blk#:MMC块设备的编号,一块是512字节
		cnt:个数
		
		从内存的addr为起始地址写数据到MMC的blk块号处,
		写数据的大小位cnt块。
		
	4》mmc erase blk# cnt
		作用:擦除MMC中的数据
		blk#:MMC块设备的编号,一块是512字节
		cnt:个数

		从MMC的blk处开始擦除数据,擦除数据的大小是cnt块。

产品阶段系统部署方式(项目完成)

【产品阶段系统部署方式(项目完成)】 			
		uboot ---》EMMC/SD卡 
		uImage ---》EMMC/SD卡 
		ramdisk.img  ---》EMMC/SD卡 	

	1. 将uboot镜像烧写到EMMC中(uboot烧写阶段已经完成)
		update_mmc 
		
	2. 将内核镜像uImage烧写到EMMC中
		系统移植\系统移植资料\镜像\uImage
		将uImage拷贝到ubuntu的tftpboot目录下
		
		tftp 0x41000000 uImage 
		mmc write 0x41000000 0x800 0x4000
		
	3. 将根文件系统镜像ramdisk.img烧写到EMMC中
		系统移植\系统移植资料\镜像\ramdisk.img
		将ramdisk.img拷贝到ubuntu的tftpboot目录下
		
		tftp 0x41000000 ramdisk.img 
		mmc write 0x41000000 0x20800 0x20800
		
	4. 设置uboot的启动参数
		bootcmd  bootargs
		
	setenv bootcmd mmc read 0x48000000 0x800 0x4000\;
		mmc read 0x49000000 0x20800 0x20800\;
		bootm 0x48000000 0x49000000

	setenv bootargs root=/dev/ram rw 
		initrd=0x49000040,0x1000000 
		rootfstype=ext4 init=/linuxrc 
		console=ttySAC0,115200

	saveenv 
	
	解析:
	root=/dev/ram :从内存中挂载根文件系统
	rw :对根文件系统具有读写的权限
	initrd=0x49000040,0x1000000
		挂载根文件系统的起始地址和大小
		跳过根文件系统的64字节的头部信息。
	rootfstype=ext4 :根文件系统的类型
	init=/linuxrc 
	console=ttySAC0,115200
	

	开发板的内存是1G大小,寻址空间是
	0x4000_0000 - 0x8000_0000
系统的部署
	开发阶段系统的部署
	u-boot镜像     : EMMC/SD/TF
	linux内核镜像  : tftp服务下载到内存中
	根文件系统     : nfs服务从服务器端去挂载
		
	setenv bootargs root=/dev/nfs nfsroot=192.168.2.149:/home/topeet/nfs/rootfs rw console=/dev/ttySAC0,115200 init=/linuxrc ip=192.168.2.213
	
	setenv bootcmd tftp 48000000 uImage\;bootm 48000000
		
产品阶段系统的部署
	u-boot镜像     : EMMC/SD/TF
	linux内核镜像  : EMMC/SD/TF
	根文件系统     : EMMC/SD/TF

	setenv bootcmd mmc read 0x48000000 0x800 0x4000\;mmc read 0x49000000 0x20800 0x20800\;bootm 0x48000000 0x49000000

	setenv bootargs root=/dev/ram rw initrd=0x49000040,0x1000000 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200

uboot启动过程主要做了什么?

uboot启动过程主要做了什么?
	分析uboot启动过程中,代码的执行主要做什么。

	ubootpak.bin的程序的入口代码(第一行代码)

1. 打开uboot源码顶层目录的u-boot.lds链接脚本文件
	  8  .text :
	  9  {
	 10   *(.__image_copy_start)
		 代码段的第一个文件
	 11   arch/arm/cpu/slsiap/s5p6818/start.o (.text*)
	 12   arch/arm/cpu/slsiap/s5p6818/vectors.o (.text*)
	 13   *(.text*)
	 14  }

2. 打开arch/arm/cpu/slsiap/s5p6818/start.S
	构建异常向量表
	 20     .globl  _stext
	 21 _stext:
	 22     b   reset
	 23     ldr pc, _undefined_instruction
	 24     ldr pc, _software_interrupt                                                              
	 25     ldr pc, _prefetch_abort
	 26     ldr pc, _data_abort
	 27     ldr pc, _not_used
	 28     ldr pc, _irq
	 29     ldr pc, _fiq

3. 通过b reset跳转到reset标签处
	 78 reset:
			保存uboot的启动参数
	 79     bl  save_boot_params
	 80     /*
	 81      * set the cpu to SVC32 mode
	 82      */
		切换CPU进入SVC模式
	 83     mrs r0, cpsr
	 84     bic r0, r0, #0x1f                                                 
	 85     orr r0, r0, #0xd3
	 86     msr cpsr,r0
	 87     禁止看门狗
	 88     /* disable watchdog */
	 89     ldr r0, =0xC0019000
	 90     mov r1, #0
	 91     str r1, [r0]
		禁止MMU和catch
	 95     bl  cpu_init_cp15
		获取CPUID,初始锁相环,选择器,内存
	 96     bl  cpu_init_crit 
	 
	 252 ENTRY(cpu_init_crit)
	 259     b   lowlevel_init       @ go setup pll,mux,memory
	 260 ENDPROC(cpu_init_crit)
	 
	 实现uboot的自搬移的过程,从flash中搬移到内存中
	100 relocate_to_text:
	101     /*
	102      * relocate u-boot code on memory to text base
	103      * for nexell arm core (add by jhkim)
	104      */
	105     adr r0, _stext              /* r0 <- current position of code   */
	106     ldr r1, TEXT_BASE           /* test if we run from flash or RAM */
	107     cmp r0, r1                  /* don't reloc during debug         */
	108     beq clear_bss
	109 
	110     ldr r2, _bss_start_ofs
	111     add r2, r0, r2              /* r2 <- source end address         */                                         
	112 
	113 copy_loop_text:
	114     ldmia   r0!, {r3-r10}       /* copy from source address [r0]    */
	115     stmia   r1!, {r3-r10}       /* copy to   target address [r1]    */
	116     cmp r0, r2                  /* until source end addreee [r2]    */
	117     ble copy_loop_text
	118 
	119     ldr r1, TEXT_BASE           /* restart at text base */
	120     mov pc, r1

	// 清除BSS段 
	122 clear_bss:
	123 #ifdef CONFIG_MMU_ENABLE
	124     bl  mmu_turn_on
	125 #endif
	126     ldr r0, _bss_start_ofs
	127     ldr r1, _bss_end_ofs
	128     ldr r4, TEXT_BASE           /* text addr */                               
	129     add r0, r0, r4
	130     add r1, r1, r4
	131     mov r2, #0x00000000         /* clear */
	132 
	133 clbss_l:str r2, [r0]            /* clear loop... */
	134     add r0, r0, #4
	135     cmp r0, r1
	136     bne clbss_l
	// 初始化C代码运行所需的栈空间
	138     ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
	139     bic sp, sp, #7                  /* 8-byte alignment for ABI compliance */
	140     sub sp, #GD_SIZE                /* allocate one GD above SP */   
	141     bic sp, sp, #7                  /* 8-byte alignment for ABI compliance */
	142     mov r9, sp                      /* GD is above SP */
	143     mov r0, #0
	// 全局数据结构体类型变量的初始化
	144     bl  board_init_f
	// 板子硬件初始化函数
	160     ldr pc, =board_init_r               /* this is auto-relocated! */


	arch/arm/lib/board.c
	710     for (;;) {
	711         main_loop();  // 死循环
	712     }

	 82     s = bootdelay_process();   获取倒计时的时间
	 83     if (cli_process_fdt(&s))   倒计时减到0之前按下任意键,进入交互模式
	 84         cli_secure_boot_cmd(s);  交互的程序
	 85 
	 86     autoboot_command(s);   自启动的程序

内核源码配置和编译的详细过程

内核源码配置和编译的详细过程 
	1> 配置交叉编译工具链,打开内核源码顶层目录的Makefile,
	将以下内容:
		195 ARCH        ?= 
		196 CROSS_COMPILE   ?= 
	修改为: 
		195 ARCH        ?= arm
		196 CROSS_COMPILE   ?= arm-none-linux-gnueabi-
	
	2> 清除中间文件	
		make clean / distclean 
	
	3> 配置内核源码支持fs6818硬件平台 
		make fs6818_defconfig
        4> 通过菜单选项的方式对内核进行配置
		make menuconfig 
        5> 编译内核生成uImage的内核镜像文件
		make -j2 uImage 
		或者make -j4 uImage 
		或者make uImage
        打印以下信息表示编译成功:
		Image Name:   Linux-3.4.39-farsight
		Created:      Mon Jul 20 15:09:28 2020
		Image Type:   ARM Linux Kernel Image (uncompressed)
		Data Size:    5391608 Bytes = 5265.24 kB = 5.14 MB
		Load Address: 40008000
		Entry Point:  40008000
		uImage内核镜像在一下目录中:
		  Image arch/arm/boot/uImage is ready

		问题1:make menuconfig 
		Your display is too small to run Menuconfig!
		It must be at least 19 lines by 80 columns.
		make[1]: *** [menuconfig] Error 1
		make: *** [menuconfig] Error 2
		原因:
		终端字体太大,缩小终端的字体
		
		问题2:make menuconfig
		第一次使用make menuconfig 需要安装图形化界面的工具
		配置之前需要安装图形图(make meuconfig):
		sudo apt-get install libncurses5-dev 
		
		
		问题3:make uImage
		在编译的过程中可能出现如下错误:
		"mkimage" command not found - U-Boot images will not be built
		make[1]: *** [arch/arm/boot/uImage] Error 1
		make: *** [uImage] Error 2
			
		错误的原因:找不到mkimage命令,
			根据提示分析出来mkimage应该存在uboot源码目录中
			uboot源码必须进行编译之后才会有mkimage可执行程序		
			
		解决问题的方法:
			将uboot源码的tools目录下的mkimage,
			拷贝到到ubuntu的/usr/bin目录下:
			sudo cp ~/uboot源码目录/tools/mkimage   /usr/bin
				      uboot目录                     ubuntu目录

			再次make uImage重新编译内核即可。


	测试生成的uImage内核镜像文件是否可以使用
		
		1》拷贝arch/arm/boot/目录下的uImage文件到tftpboot目录下
		
		2》设置开发板的系统启动方式
			开发阶段系统的部署和自启动的模式
			tftp 下载内核 
			nfs挂载根文件系统
			
			bootcmd 
			bootargs
		3》系统启动成功,说明内核编译成功	

make fs6818_defconfig命令执行过程详解

make fs6818_defconfig命令执行过程详解
	
1. 打开内核源码顶层目录的Makefile文件,
	搜索fs6818_defconfig,没有搜索到;
	搜索%config,搜索到一下信息

	491 %config: scripts_basic outputmakefile FORCE                                
	492     $(Q)mkdir -p include/linux include/config
	493     $(Q)$(MAKE) $(build)=scripts/kconfig $@

	$@ : 目标
	$^ :所有的依赖
	$< :第一个依赖

	解析:
	Q = @
	mkdir -p include/linux include/config
	make -f scripts/Makefile.build obj=scripts/kconfig fs6818_defconfig
	进入scripts/kconfig目录下执行make fs6818_defconfig

2. 打开scripts/kconfig目录下的Makefile文件
	搜索%_defconfig,得到以下信息
	95 %_defconfig: $(obj)/conf
	96     $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
	解析:
	scripts/kconfig/conf --defconfig=arch/arm/configs/fs6818_defconfig Kconfig
	
	使用file命令查看scripts/kconfig目录下conf文件的类型
	file scripts/kconfig/conf
	可知conf文件是一个elf可执行文件
	
	通过以上分析可知,conf文件根据arch/arm/configs/
	目录下的fs6818_defconfig默认配置文件和内核源码
	顶层目录的Kconfig文件生成.config文件。

make menuconfig执行过程详解

make menuconfig执行过程详解
1. 	搜索menuconfig,没有搜索到;
	搜索%config,搜索到一下信息

	491 %config: scripts_basic outputmakefile FORCE                                
	492     $(Q)mkdir -p include/linux include/config
	493     $(Q)$(MAKE) $(build)=scripts/kconfig $@

	解析:
	Q = @
	mkdir -p include/linux include/config
	make -f scripts/Makefile.build obj=scripts/kconfig menuconfig
	进入scripts/kconfig目录下执行make menuconfig
2. 打开scripts/kconfig目录下的Makefile文件
	搜索menuconfig,得到以下信息
	 20 menuconfig: $(obj)/mconf                                                    
	 21     $< $(Kconfig)
	
	解析:
	scripts/kconfig/mconf Kconfig
	
	使用file命令查看scripts/kconfig目录下mconf文件的类型
	file scripts/kconfig/mconf
	可知mconf文件是一个elf可执行文件
	
	mconf根据内核源码顶层目录的Kconfig文件生成
	图形化界面的菜单选项配置界面。

3. 打开内核源码顶层目录的Kconfig文件
	  5 mainmenu "Linux/$ARCH $KERNELVERSION Kernel Configuration"
	  6 
	  7 config SRCARCH
	  8     string
	  9     option env="SRCARCH"
	 10 
	 11 source "arch/$SRCARCH/Kconfig" 

	解析: 
	mainmenu : 主菜单
	语法格式:mainmenu  "主菜单名字"
	
	source:包含下一级子菜单对应的Kconfig文件路径
	语法格式: source "下一级子菜单的Kconfig路径"
	
	打开arch/arm/目录下的Kconfig文件。

	Kconfig文件作用?
		Kconfig用于存放菜单选项的配置信息。

	1. 主菜单 
		包含:子菜单,菜单选项
	2. 子菜单:
		包含:子菜单,菜单选项
	3. 菜单选项



版权声明:本文为Linux_zhicheng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。