天天看点

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

目录

  • 前言
  • 文档
    • 用户指南
    • uboot应用开发指南
  • SDK中相关脚本学习
    • sdk.cleanup阅读
    • sdk.unpack阅读
    • scripts/common.sh
  • osdrv

前言

SDK中会做好很多功能,如果对SDK不熟悉那么很可能花很长一段时间进行开发结果发现SDK已经提供了接口。

所以在项目开始前,对SDK进行学习非常有必要。

文档

用户指南

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

介绍了环境搭建相关内容

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

本次学习采用的HI3528E开发板主要使用了串口线及网线进行调试。

JTAG虽然也提供了,但是没有用到。一般JTAG用于较为底层(uboot)的功能调试。

uboot是海思官方已经开发好的,在实战和工作当中很少去调试,除非是基于海思的uboot去开发一些更高级的功能。

uboot应用开发指南

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

提供了uboot移植相关内容指导

SDK中相关脚本学习

目录在

Hi3518E V200R001C01SPC030\01.software\board

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

解压开进入文件夹

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

这两个是脚本文件

scripts中也有一个脚本文件

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

我们首先需要研究这三个脚本文件

这三个脚本文件的内容是我们整个package中所有内容怎么解压开,怎么去配置编译的,怎么编译uboot,怎么编译内核这些东西的指导,是别人已经做好了的。

我们只要将这三个脚本文件研究清楚,那么我们就能随便玩这个SDK了。

于是我们需要去分析这个脚本文件,然后再根据脚本文件的内容和我们自己的理解去实现一定的功能。

功能方面,从文件名不难看出

  • sdk.cleanup——清理
  • sdk.unpack——解压

sdk.cleanup阅读

内容如下

#!/bin/sh
source scripts/common.sh

ECHO "Cleanup SDK" COLOR_YELLOW	

ECHO ""
WARN "ALL THE SOUCE FILES WILL BE DELETED, FILES YOU MOTIFIED/ADDED WILL BE LOST !!!"
ECHO ""

#ECHO "To continue, type 'Yes' and then press ENTER ..."

#read choice
#[ x$choice != xYes ] && exit 1

set +e

ECHO "cleanup drv"
pushd .
run_command_progress_float "rm drv -frv" 0 "find drv | wc -l"
popd

ECHO "cleanup mpp"
pushd .
run_command_progress_float "rm mpp* -frv" 0 "find mpp* | wc -l"
popd

ECHO "cleanup osdrv"
pushd .
run_command_progress_float "rm osdrv -frv" 0 "find osdrv | wc -l"
popd

           

第一行的

#!/bin/sh

说明这是一个shell脚本

第二行

source scripts/common.sh

是将

scripts/common.sh

复制到这里,和include的头文件包含类似。

scripts文件夹中的common.sh中定义了很多函数。可以理解为common.sh是库函数,另外两个为main函数。

第三行

ECHO "Cleanup SDK" COLOR_YELLOW

先打印一个 Cleanup SDK,颜色为黄色

后面几行一样是打印

WARN “ALL THE SOUCE FILES WILL BE DELETED, FILES YOU MOTIFIED/ADDED WILL BE LOST !!!”

所有源文件将删除,你添加/修改的文件将丢失

这里说的是解压开的文件。我们需要在执行cleanup之前将修改过的文件做备份。

#ECHO "To continue, type 'Yes' and then press ENTER ..."

#read choice
#[ x$choice != xYes ] && exit 1
           

后面读取输入的指令,不等于yes就退出

最后一部分

pushd . 是保存当前目录

然后执行

scripts/common.sh

run_command_progress_float

函数

执行这个脚本,效果如下

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

发现./不能执行,但是source可以执行。

具体没有去了解,以结果为导向的话能用就可以了

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

sdk.unpack阅读

#!/bin/sh
source scripts/common.sh

ECHO "Unpacking SDK" COLOR_YELLOW

WARN "Be sure you have installed the cross-compiler. if not, install it first!"
WARN "ALL THE SOUCE FILES WILL BE OVERWRITED, FILES YOU MOTIFIED WILL BE LOST !!!"
ECHO ""

#ECHO "To continue, type 'Yes' and then press ENTER ..."

#read choice
#[ x$choice != xYes ] && exit 1

set +e

#ECHO "install cross toolchain"
#./tools/toolchains/cross.install

ECHO "unpacking osdrv"
mkdir -p osdrv/
run_command_progress_float "tar -xvzf package/osdrv.tgz" 0 "tar -tzf package/osdrv.tgz | wc -l"

ECHO "unpacking kernel"
mkdir -p osdrv/
run_command_progress_float "tar -xvzf osdrv/opensource/kernel/linux-3.4.y.tgz -C osdrv/opensource/kernel/" 0 "tar -tzf osdrv/opensource/kernel/linux-3.4.y.tgz | wc -l"

if [ "$SDK_CHIP" = "hi3519" ]; then
#ECHO "unpacking mpp_single"
#mkdir -pv mpp_single
#run_command_progress_float "tar -xvzf package/mpp_single.tgz" 0 "tar -tzf package/mpp_single.tgz | wc -l"

ECHO "unpacking mpp_big-little"
mkdir -pv mpp_big-little
run_command_progress_float "tar -xvzf package/mpp_big-little.tgz" 0 "tar -tzf package/mpp_big-little.tgz | wc -l"
else
ECHO "unpacking mpp"
mkdir -pv mpp
run_command_progress_float "tar -xvzf package/mpp.tgz" 0 "tar -tzf package/mpp.tgz | wc -l"
fi

ECHO "unpacking drv"
mkdir -pv drv
run_command_progress_float "tar -xvzf package/drv.tgz" 0 	"tar -tzf package/drv.tgz | wc -l"
           

阅读完上面的cleanup后,这里就粗略的阅读一下

首先打印出来,要求使用者先安装交叉编译工具链。

如果之前解压过修改过,再执行unpack的话,会将原来的文件覆盖掉。

在当前目录下创建

osdrv

这个目录

运行

run_command_progress_float

这个函数

解压

package/osdrv.tgz

下面对芯片的型号进行判断,显然我们使用的不是3519。

于是进入else

解压

mpp.tgz

最后解压

package/drv.tgz

执行如下

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

虽然上面的打印让我们先安装交叉编译工具链,但是通过阅读发现,脚本后面的内容都是解压没有编译,所以没有关系。

解压完前后对比如下

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv
海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv
  • drv——驱动
  • mpp——一些库
  • osdrv——uboot和kernel

于是我们需要重点研究osdrv中的内容

scripts/common.sh

#!/bin/sh

#set -e

# for debug
DEBUG_LOG_FILE='&2'
DEBUG_LOG_LEVEL=0

# ANSI COLORS
COLOR_CRE="[K"
COLOR_NORMAL="[0;39m"
COLOR_RED="[1;31m"
COLOR_GREEN="[1;32m"
COLOR_YELLOW="[1;33m"
COLOR_BLUE="[1;34m"
COLOR_MAGENTA="[1;35m"
COLOR_CYAN="[1;36m"
COLOR_WHITE="[1;37m"

# Shell command
TAR=tar
CP=/bin/cp
RM=/bin/rm
GREP=grep
SED=sed
MKDIR=mkdir
CHMOD=chmod
MV=mv
CD=cd
LN=ln
MAKE=make
MKNOD=mknod
PUSHD=pushd 
POPD=popd 
RMDIR=rmdir
DEPMOD=/sbin/depmod
RMDIR=rmdir
MKIMG=mkimage
PATCH=patch
DIFF=diff
TOUCH=touch
CAT=cat

e_blank='[        ][      ]*'
e_year='20[0-9][0-9]'
e_month='([1-9]|0[1-9]|1[0-2])'
e_day='([1-9]|0[1-9]|[12][0-9]|3[0-1])'
e_time='([01][0-9]|2[0-3]):[0-5][0-9]'
e_employid='[a-zA-Z][a-zA-Z]*[0-9]{4,}'

#$1: string
#$2: color
ECHO()
{
	[ -n "$2" ] && eval echo -n \"\${${2}}\";
	echo "${1}${COLOR_NORMAL}"
}

ERR()
{
	echo "${COLOR_RED} ERR: ${1}${COLOR_NORMAL}" >&2
}

WARN()
{
	echo "${COLOR_YELLOW}WARN: ${1}${COLOR_NORMAL}" >&2
}

# $1:
LOG()
{
	echo "$1"
}


#$1: string
#$2: level
DEBUG()
{
	local level=$2
	[ -z "$level" ] && { level=0; }
	[ $level -lt $DEBUG_LOG_LEVEL ] && return 0;

	echo "$COLOR_WHITE$1$COLOR_NORMAL" > $DEBUG_LOG_FILE
}

# $1: command
# $2: LR/CR steps
run_command_progress()
{
	local n=0
	local steps=$2
	local progress_bar=""
	local counter=0
	local files=0

	ECHO "run_command_progress: '$1'" 
	[ -z "$steps" ] && { steps=1; }

	[ -n "$3" ] && [ -d "$3" ] && { steps=`find $3 | wc -l`; steps=`expr $steps / 50`; }

	eval $1 | while read line
	do
		#((n++))
		#((files++))
		((++n))
		((++files))

		if [ $n -ge $steps ] ;
		then
			#((counter++))
			((++counter))
			if [ $counter -le 50 ] ;
			then
				progress_bar="$progress_bar#";
				printf "     --------------------------------------------------|\r[%03d]$progress_bar\r" $steps
			else
				printf "[%03d#$progress_bar|\r" `expr $files / 50`
			fi

			n=0
		fi
	done

	echo ""
}

# $1: command
# $2: total
# $3: command to calc totals
run_command_progress_float()
{
	local readonly RCP_RANGE=50
	local rcp_lines=0
	local rcp_nextpos=1
	local rcp_total=0
	local progress_bar=
	local rcp_prog=0
	local rcp_tmp=0
	local prog_bar_base=
	local rcp_percent=0

	ECHO "run_command_progress_float: '$1'" 

	if [ -n "$3" ] ;
	then
		echo -n "Initializing progress bar ..."
		rcp_total=`eval $3`;
		echo -n "\r"
		[ -z "$rcp_total" ] && rcp_total=1
	else
		[ -n "$2" ] && rcp_total=$2
	fi

	[ -z "$rcp_total" ] && rcp_total=1
	[ $rcp_total -le 0 ] && rcp_total=1

	prog_bar_base="[    ]"
	while [ $rcp_tmp -lt $RCP_RANGE ]
	do
		prog_bar_base="$prog_bar_base-"
		#((rcp_tmp++)) 
		((++rcp_tmp)) 
	done
	prog_bar_base="${prog_bar_base}|"
	printf "\r$prog_bar_base\r"

	set +e
	eval $1 | while read line
	do
		#((rcp_lines++))
		((++rcp_lines))

		if [ $rcp_lines -ge $rcp_nextpos ]
		then
			rcp_percent=`expr \( $rcp_lines \* 101 - 1 \) / $rcp_total `
			rcp_prog=`expr \( $rcp_lines \* \( $RCP_RANGE + 1 \) - 1 \) / $rcp_total `
			[ $rcp_prog -gt $RCP_RANGE ] && rcp_prog=$RCP_RANGE
			rcp_nextpos=`expr \( \( $rcp_percent + 1 \) \* $rcp_total \) / 100`
			[ $rcp_nextpos -gt $rcp_total ] && rcp_nextpos=$rcp_total

			rcp_tmp=0
			progress_bar=""
			while [ $rcp_tmp -lt $rcp_prog ]
			do
				progress_bar="$progress_bar#"
				((rcp_tmp++))
			done
			printf "\r$prog_bar_base\r[%3d%%]$progress_bar\r" $rcp_percent
		fi
	done
	set -e

	echo ""
}

#$1: path
abs_path()
{
	pushd "$1" >/dev/null
	[ $? -ne 0 ] && return 1;
	pwd
	popd >/dev/null
}

#$1: $cfg_moddir is multi
prepare_unpacking_cleanup()
{
	$CAT >> $HCM_SH_SDKINSTALL << EOF

ECHO "unpacking $cfg_moddir"
mkdir -pv $module_basedir
run_command_progress_float "tar -xvzf `sub_dir $dir_postbuild_srctarball $HCM_DESTDIR`/$module_dirname.tgz -C $module_basedir/" 0 \
	"tar -tzf `sub_dir $dir_postbuild_srctarball $HCM_DESTDIR`/$module_dirname.tgz | wc -l"
EOF

if [ -z "$1" ] ;
then
	$CAT >> $HCM_SH_SDKCLEANUP << EOF

ECHO "cleanup $cfg_moddir"
run_command_progress_float "rm $cfg_moddir -frv" 0 "find $cfg_moddir | wc -l"
EOF
else
	$CAT >> $HCM_SH_SDKCLEANUP << EOF

ECHO "cleanup $cfg_moddir"
pushd $module_basedir
run_command_progress_float "rm $cfg_moddir -frv" 0 "find $cfg_moddir | wc -l"
popd
EOF
fi

}

# $1: prefix
# $2..$n: dirs list
make_dirs()
{
	local make_dirs_count=2
	local make_dirs_dir=

	[ -z "$1" ] && { ERR "make_dirs mast have a prefix dir!"; return 1; }
	$MKDIR $1 -p

	while true
	do
		eval make_dirs_dir=\${$make_dirs_count}
		[ -z "$make_dirs_dir" ] && break;
		$MKDIR $1/$make_dirs_dir -p
		#((make_dirs_count++))
		((++make_dirs_count))
	done
}

check_dir_empty()
{
	[ -z "$1" ] && return 0;
	! [ -d $1 ] && return 0;
	[ -z "`find $1/ -maxdepth 1 -mindepth 1`" ] && return 0;

	return 1
}

# $1 - $2
# $3: frefix for '/', like "\\\\/"
sub_dir()
{
	local subdir=
	local dirA=`dirname $1/stub`
	local dirB=`dirname $2/stub`

	while [ "$dirA" != "$dirB" ] && [ "$dirA" != "." ] && [ "$dirA" != "/" ] 
	do
		if [ -z "$subdir" ] ; then
			subdir=`basename $dirA`
		else
			subdir=`basename $dirA`$3/$subdir
		fi
		dirA=`dirname $dirA`
	done

	[ -z "$subdir" ] && subdir=.

	dirname $subdir/stub
}

# $1: base dir
# $2: dest dir
# $3: frefix for '/', like "\\\\/"
base_offset_dir()
{
	local ofstdir=`sub_dir $2 $1`
	local bodofst=

	while [ "$ofstdir" != "." ] && [ "$ofstdir" != "/" ] 
	do
		if [ -z "$bodofst" ] ; then
			bodofst=..
		else
			bodofst=..$3/$bodofst
		fi
		ofstdir=`dirname $ofstdir`
	done

	dirname $bodofst/stub
}

#$1: dir
set_drv_kbuild()
{
	local cc_file=Makefile
	local mbdir= 

	for mbdir in $1 $1/*
	do
		if [ -f $mbdir/$cc_file ] ;
		then
			local kbuild_dir_adj="`base_offset_dir $HCM_DESTDIR $mbdir "\\\\"`\\/`echo "$HCM_SDKDIR_KBUILD" | \
				sed -n "s/\//\\\\\\\\\//gp"`"

			$SED -i "s/^KERNEL_MAKE[ \t]*:=.*/KERNEL_MAKE := -C $kbuild_dir_adj/" $mbdir/$cc_file
		fi
	done	
}

#$1: name
#$2: level
write_rootfs_level()
{
	local rlevel_config=$HCM_DESTDIR/$HCM_SDKDIR_RESOURCE/rlevel.config
	$TOUCH $rlevel_config
	[ -n "`grep "^\[[0-9A-Za-z][0-9A-Za-z\-]*\]	$1$" < $rlevel_config`" ] && { \
       		WARN "$rlevel_config already have item '$1'"
		return 0;
	}
	echo "[$2]	$1" >> $rlevel_config
}

#$1: 
remove_all_cvsdir()
{
	! [ -d "$1" ] && { WARN "'$1' not found when remove 'CVS' directories."; return ; }

	ECHO "Remove: 'CVS' directories in $1"
	find $1 -type d -name "CVS" | xargs rm -fr
}

#$1: strip command
#$2: file list
strip_elf()
{
	for file in $2
	do
		[ -z "`file $file | grep "ELF .* executable, .*, not stripped"`" ] && continue

		ECHO "$1 $file"
		$1 $file
	done
}

#$1: strip command
#$2: file list
strip_lib()
{
	for file in $2
	do
		[ -z "`file $file | grep "ELF .* shared object, .*, not stripped"`" ] && continue

		ECHO "strip not really done: $file"
	done
}

# $1: rootfs base
# $2: modules list
install_extern_kmod()
{
	local iek_installed_modules=
	local iek_dest_module=
	local iek_depend_info=
	local iek_install_base=

	pushd $1 >/dev/null
	iek_install_base=$PWD
	popd >/dev/null

	for iek_extmod in `find $2`
	do
		iek_dest_module=/$HCM_INROOTFS_EXTKMOD/`basename $iek_extmod`

		[ -f $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$iek_dest_module ] && \
			{ WARN "Extern module $iek_extmod conflict: $iek_dest_module"; sleep 1; }

		iek_installed_modules="$iek_installed_modules $iek_dest_module"
		$CP -uf $iek_extmod $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$iek_dest_module
	done

	pushd $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE >/dev/null

	ECHO "Generating modules dependency ..."
	$DEPMOD -ae -b ./ -r -F $HCM_DESTDIR/$HCM_SDKDIR_KBUILD/System.map $HCM_KERNEL_RELEASE

	for iek_extmod in $iek_installed_modules
	do
		iek_depend_info=`grep "^$iek_extmod:" < $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$HCM_INROOTFS_DEPKMOD/modules.dep | sed "s/\://"`
		for iek_extmod in $iek_depend_info
		do
			$CP -uf --parents .$iek_extmod $iek_install_base/
			[ x$cfg_install_strip == xyes ] && $HCM_CROSS_COMPILE-strip $iek_install_base$ikm_kmod -g -S -d

		done
	done

	popd >/dev/null
}

# $1: dest rootfs based
# $2: module list
install_kernel_module()
{
	local ikm_kmod_resdir=$HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE
	local ikm_install_basedir=
	local ikm_kmod=

	pushd $1 >/dev/null
	ikm_install_basedir=$PWD
	popd  >/dev/null

	pushd $ikm_kmod_resdir >/dev/null
	$DEPMOD -ae -b ./ -r -F $HCM_DESTDIR/$HCM_SDKDIR_KBUILD/System.map $HCM_KERNEL_RELEASE

	while read ikm_kmod
	do
		ikm_depend_info=`grep "^$ikm_kmod:" < $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$HCM_INROOTFS_DEPKMOD/modules.dep | sed "s/\://"`
		for ikm_kmod in $ikm_depend_info
		do
			$CP -uf --parents .$ikm_kmod $ikm_install_basedir
			[ x$cfg_install_strip == xyes ] && $HCM_CROSS_COMPILE-strip $ikm_install_basedir$ikm_kmod -g -S -d
		done
	done << EOF
	`pushd $HCM_INROOTFS_KERNMOD >/dev/null; \
		eval find "$2" -type f -printf \"/$HCM_INROOTFS_KERNMOD/%p\\\n\"; \
		popd >/dev/null`
EOF

	popd >/dev/null
}

string_to_varname()
{
	echo "$1" | sed 's/[^a-zA-Z0-9_]/_/g'
}

patchset_get_param()
{
	echo "$1" | cut -d')' -f1 | sed 's/[\(\|]/ /g'
}

patchset_get_name()
{
	echo "$file" | cut -d')' -f2
}
           

内容较长,一部分一部分的看。

这个脚本里边主要定义了一些函数。

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

这部分是颜色数值,像我们之前在操作linux的时候出现的很多有颜色的字符就是这么来的。

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

这部分定义了一些命令。

为什么要定义这些命令?

和宏定义类似,这个脚本可能不光在sh里用,将来可能在别的里面用,命令可能需要替换,所以定义。

另外两个脚本都用到的

run_command_progress

函数,实际上就是显示解压进度条。

还有另一个进度条相关的函数

# $1: command
# $2: total
# $3: command to calc totals
run_command_progress_float()
           

有三个参数,一个是命令,一个是总量,一个是计算百分比

这个函数是通过小数点显示

运行的效果如下

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

关于脚本,只需要能看懂它大概是干什么的就可以,实际工作场景中脚本都是写好的,用就行了

osdrv

上面说的,解压出来的重点就是

osdrv

这个文件夹

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

接下来对

uboot

kernel

进行学习

osdrv

中有一个

readme

makefile

,先看这两个

makefile中写了

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

这边做了两个交叉编译选项来选择对应的交叉编译工具链。

uclibc和glibc的区别

  • glibc功能全,但是占空间大
  • uclibc是glibc的精简版本,保留了必要的功能,体积非常小

实际产品的flash只有8兆,在这种情况下只能使用

uclibc

glibc

光是这个库都放不下就更不用说其他的东西了。

使用

glibc

的产品大多为板载的不是SPI Flash,用的是TF卡或者EMMC。所以不用考虑

glibc

的两三百兆。

其他内容就是一些命令

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv
海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

执行发现交叉编译工具链没有找到,此时需要查看

makefile

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

可以看到,虽然编译选项中给了交叉编译工具链的选择,但是

makefile

中没有绝对路径。

makefile

中的写法就是访问当前目录,所以找不到

继续浏览

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

发现,需要在当前目录下有一个

arm-hisiv300-linux

目录,这个目录下放对应的交叉编译工具链才行。

交叉编译工具链的脚本文件中给出了安装工具链的路径,我们可以改makefile或者这里的路径,再或者直接把压缩包拷贝到相应路径中

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

我们选择最简单的方式

于是我们需要将交叉编译工具链安装到

osdrv

底下

交叉编译工具链在

/osdrv/opensource/toolchain/

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

接着,我们将其中的压缩包移动到

/osdr

底下并解压

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

有了这个路径,这样makefile就可以找到它,如下图

海思3518E开发笔记1.2——海思SDK脚本学习前言文档SDK中相关脚本学习osdrv

然后这样配置了之后还是报错找不到交叉编译工具链

这是由于32位的工具链和64位工具链不同导致的

下一期给出解决方案