
/***************************************************************************************************
* u-boot裁剪
*
*/
board -------->只留与扳机相关的文件夹
cpu -------->只留与扳机相关的文件夹
include -------->与架构无关的目录删除
include/configs -------->只留架构相关的一个文件
include/asm -------->删除与架构无关的目录
./ -------->主目录lib开头与架构无关的目录删除,注意报libfdt留下
/***************************************************************************************************
* makefile 关键说明
*
*/
make ming2440_config流程:
make mini2440_config
--> mini2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 risecomm s3c24x0
--> mkconfig
mini2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 risecomm s3c24x0
// $(A:patternA=patternB)。意思就是将 A中 patternA格式的字符用patternB来代替。回归$(@:_config),
// @代表输入的参数,即:mini2440_config,patternA是_config,patternB是空的。说白了就是将mini2440_config的_config去掉。
@$(MKCONFIG) $(@:_config=) arm arm920t mini2440 tekkamanninja s3c24x0
// 查找MKCONFIG,MKCONFIG就是uboot目录下的那个mkconfig这个文件,这条语句就是:运行mkconfig文件,并传递 6个参数进去
mkconfig文件:
作用:建立include目录下的link目录(asm),include目录下创建confg.mk文件,创建config.h文件。
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
TARGETS=""
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
-t) shift ; TARGETS="`echo $1 | sed 's:_: :g'` ${TARGETS}" ; shift ;;
*) break ;;
esac
done
// $#是脚本传递的参数的个数。-gt是>的意思。 $1:第一个参数。shift:奸杀第一个参数,
// 将第二参数变成第一个……这段代码意思 检查参数中,有无-a -n -t这样的参数,没有的话直接break。
// 很明显,makefile传递的6个参数,没有-a,-t,-n。直接break。
[ "${BOARD_NAME}" ] || BOARD_NAME="$1" // :["${BOARD_NAME}"]表示一个条件,BOARD_NAME != NULL, ||表示如果 条件为假 则运行后面的程序。 同时&&表示如果条件为真,则运行后面的程序
// BOARD_NAME等于传进来的第一个参数,即BOARD_NAME=mini2440
[ $# -lt 4 ] && exit 1 // 小于4个参数则退出
[ $# -gt 6 ] && exit 1 // 大于6个参数则退出
if [ "${ARCH}" -a "${ARCH}" != "$2" ]; then // 判断ARCH变量值是否为BULL ,-a是and的意思,并且 ARCH!= $2
echo "Failed: \\$ARCH=${ARCH}, should be '$2' for ${BOARD_NAME}" 1>&2
exit 1
fi
echo "Configuring for ${BOARD_NAME} board..."
// 建立
asm连接
// Create link to architecture specific headers
//
if [ "$SRCTREE" != "$OBJTREE" ] ; then // 都为null,相等,所以运行else后面
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/include/asm-$2 asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -rf asm-$2
rm -f asm
mkdir asm-$2
ln -s asm-$2 asm
else
cd ./include
rm -f asm
ln -s asm-$2 asm
fi
rm -f asm-$2/arch
if [ -z "$6" -o "$6" = "NULL" ] ; then // -z的意思是判断字符串是否为"" -o是或的意思, 判断语句意思是$6=="" 或者$6==NULL
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch // asm-arm下建立连接文件arch,link到arch-s3c24x0
fi
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
# 把芯片信息输出到config.mk文件中
# Create include file for Make
#
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
# Assign board directory to BOARDIR variable
if [ -z "$5" -o "$5" = "NULL" ] ; then
BOARDDIR=$4
else
BOARDDIR=$5/$4
fi
/***************************************************************************************************
* u-boot支持go命令的方法
* 在cmd_boot.c文件中(没有就自己创建)增加以下内容
*/
/* 1、添加call_linux函数*/
void call_linux(long a0, long a1, long a2){
__asm__(
" mov r1, #0\\n"
" mov r1, #7 << 5\\n" /* 8 segments */
"1: orr r3, r1, #63 << 26\\n" /* entries */
"2: mcr p15, 0, r3, c7, c14, 2\\n" /* clean & invalidate D index */
" subs r3, r3, #1 << 26\\n"
" bcs 2b\\n" /* entries to 0 */
" subs r1, r1, #1 << 5\\n"
" bcs 1b\\n" /* segments 7 to 0 */
" mcr p15, 0, r1, c7, c5, 0\\n" /* invalidate I cache */
" mcr p15, 0, r1, c7, c10, 4\\n" /* drain WB */
);
__asm__(
"mov r0, #0\\n"
"mcr p15, 0, r0, c7, c10, 4\\n" /* drain WB */
"mcr p15, 0, r0, c8, c7, 0\\n" /* invalidate I & D TLBs */
);
// 以上的内容可以不要
// r0、r1、r2三个寄存器的参数是传递到内核head.S文件中,r0:0,r1:体系结构号,r2地址
__asm__(
"mov r0, %0\\n" // 获取0号,也就是第一个(a0)的数据
"mov r1, #0x0c1\\n" // 查芯片相关资料,mini2440的为 1999
"mov r2, %2\\n" // 启动地址 mini2440=0x30008000
"mov ip, #0\\n"
"mcr p15, 0, ip, c13, c0, 0\\n" /* zero PID */
"mcr p15, 0, ip, c7, c7, 0\\n" /* invalidate I,D caches */
"mcr p15, 0, ip, c7, c10, 4\\n" /* drain write buffer */
"mcr p15, 0, ip, c8, c7, 0\\n" /* invalidate I,D TLBs */
"mrc p15, 0, ip, c1, c0, 0\\n" /* get control register */
"bic ip, ip, #0x0001\\n" /* disable MMU */
"mcr p15, 0, ip, c1, c0, 0\\n" /* write control register */
"mov pc, r2\\n""nop\\n""nop\\n"
: /* no outpus */
: "r" (a0), "r" (a1), "r" (a2));
}
/****************************************************************************
2、 添加setup_linux_param函数
****************************************************************************/
static void setup_linux_param(ulong param_base){
struct param_struct *params = (struct param_struct *)param_base;
char *linux_cmd;
// 获取bootargs参数
linux_cmd = getenv("bootargs");
memset(params, 0, sizeof(struct param_struct));
params->u1.s.page_size = 0x00001000; // DDR的页大小
params->u1.s.nr_pages = (0x04000000 >> 12); // 页数
/* set linux command line */
memcpy(params->commandline, linux_cmd, strlen(linux_cmd) + 1);
}
/***************************************************************************************************
* u-boot中MAC地址设置及往内核中传递
*
*/
//1.解决uboot命令行中不能设置ethaddr的问题,经常会提示:Can't overwrite "ethaddr":
common/cmd_nvedit.c中函数_do_setenv中找到
1 #ifndef CONFIG_ENV_OVERWRITE
190
191 /*
192 * Ethernet Address and serial# can be set only once,
193 * ver is readonly.
194 */
195 #ifdef CONFIG_HAS_UID
196 /* Allow serial# forced overwrite with 0xdeaf4add flag */
197 if ( ((strcmp (name, "serial#") == 0) && (flag != 0xdeaf4add)) ||
198 #else
199 if ( (strcmp (name, "serial#") == 0) ||
200 #endif
201 ((strcmp (name, "ethaddr") == 0)
202
203 #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
204 && (strcmp ((char *)env_get_addr(oldval),MK_STR(CONFIG_ETHADDR)) != 0)
205 #endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */
206 ) ) {
207 printf ("Can't overwrite \\"%s\\"\\n", name);
208 return 1;
209 }
210 #endif
把201行替换成 (0 即可;
2.为了让uboot命令行中设置的参数ethaddr传递到内核,必须修改uboot和linux内核两个地方:
(1)uboot修改 : lib_arm/armlinux.c
在 247 #ifdef CONFIG_CMDLINE_TAG
248 setup_commandline_tag (bd, commandline);
下面添加如下语句:
char *buf1 = malloc(1024);
sprintf(buf1, "%s mac=%s", getenv ("bootargs"), getenv ("ethaddr"));
setup_commandline_tag (bd, buf1);
(2)linux内核修改:drivers/net/davinci_emac.c
static int emac_eth_setup(void)
19 {
前面添加:
static char davinci_mac_addr_uboot[20] = "";
1887 static int __init param_mac_setup(char *str)
1888 {
18 strncpy
(davinci_mac_addr_uboot, str, sizeof(davinci_mac_addr_uboot));
10 }
11 __setup("mac=", param_mac_setup);
并在函数emac_eth_setup内部语句printk("TI DaVinci EMAC: MAC address is %s\\n", emac_eth_string);前面添加:
strncpy(emac_eth_string, davinci_mac_addr_uboot, sizeof(emac_eth_string));
/***************************************************************************************************
* u-boot一些特殊错误
*
*/
1、当一个已经编译过的u-boot,再次配置编译,发送无法编辑板级信息也无法编译,提示:
$make ok2440_config
configuring for ok2440 board ...
rm:无法删除 "asm-arm/arch":是一个目录 等信息
解决方法。
1、手动删除源码根目录下的include/asm 文件夹
分析:
原因:linux/include/asm 文件夹是内核编译过程中创建的,创建结果就是一个指向文件夹asm-arm的链接,表明该系统的平台是arm架构的 ,而编译系统内核之前,是没有asm这个链接的,所以,在编译过程中,创建该链接时文件名字与asm文件夹的名字发生冲突,报错了
2、在Uboot顶层有个mkconfig文件,你打开后在里面所有rm后面都加上-r
比如源代码是rm -d asm-arm/arch改成 rm -rd asm- arm/arch即可 意思就是强行删除
2、本来make时时正常的,但make clean之后再make就出错了
原因:
主要是出现在源码没有写好和配置不对,本来正常是因为没有make clean导致u-boot内部很多信息都没有重新检查,只是检查一些修改的更新,所以有些错误无法检查到,而make clean之后再make所有的规则都要重新检查,有错误就检查出来了
3、u-boot拷贝到其他机器编译时,往往会出现没有规则文件的错误,这时首先要执行:
make distclean ----> make 板级号_config(如:make mini2440_config) ---> make
