smali简介及反编译应用

最后更新于:2022-04-01 23:27:36

';

安卓下app应用举例

最后更新于:2022-04-01 23:27:33

';

mxnet

最后更新于:2022-04-01 23:27:31

';

讯飞SDK

最后更新于:2022-04-01 23:27:29

';

opencv

最后更新于:2022-04-01 23:27:27

';

linux下app应用举例

最后更新于:2022-04-01 23:27:24

';

camdriod 走读

最后更新于:2022-04-01 23:27:22

# camdriod编译过程走读 ## camdroid编译 ~~~ source build/envsetup.sh #导入环境变量设置,如下面的这些命令 lunch #选择平台型号,在build/envsetup.sh,包含了device/softwinner/common/vendorsetup.sh mklichee #编译BootLoader和内核,模块 extract-bsp #拷贝前面的结果 make -j12 #编译camdroid pack #打包镜像 ~~~ ## lichee编译 mklichee在device/softwinner/common/vendorsetup.sh里: ~~~ function mklichee() { mksetting mk_info "build lichee ..." mkbr && mkkernel # mkbr && mkkernel && mkuboot [ $? -ne 0 ] && return 1 return 0 } ~~~ ### mksetting打印配置信息 ~~~ function mksetting() { printf "\n" printf "mkscript current setting:\n" printf " Chip: ${LICHEE_CHIP}\n" printf " Platform: ${LICHEE_PLATFORM}\n" printf " Board: ${LICHEE_BOARD}\n" printf " Output Dir: ${LICHEE_PLAT_OUT}\n" printf "\n" } ~~~ 实际打印结果: > mkscript current setting: > Chip: sun8iw8p1 > Platform: > Board: > Output Dir: /home/zp/develop/lichee_git/lichee_zero/camdroid/../lichee/out/sun8iw8p1/linux/common ### mkbr编译buildroot ~~~ function mkbr() { mk_info "build buildroot ..." local build_script build_script="scripts/build.sh" LICHEE_PLATFORM="linux" (cd ${LICHEE_BR_DIR} && [ -x ${build_script} ] && ./${build_script} "buildroot" ${LICHEE_PLATFORM} ${LICHEE_CHIP}) [ $? -ne 0 ] && mk_error "build buildroot Failed" && return 1 mk_info "build buildroot OK." } ~~~ 执行结果: ~~~ INFO: build buildroot ... external toolchain has been installed INFO: build buildroot OK. ~~~ > export LICHEE_BR_DIR=${LICHEE_DIR}/buildroot 所以先进入lichee/buildroot, -x表示进入跟踪模式,执行scripts/build.sh,这里是导入了一些路径变量 ~~~ EXTERNAL_DIR=${LICHEE_BR_DIR}/external-packages DESTDIR=${LICHEE_BR_DIR}/images STAGING_DIR=${LICHEE_BR_OUT}/staging INCDIR=${STAGING_DIR}/usr/include TARGET_DIR=${LICHEE_BR_OUT}/target TARGET_SYSROOT_OPT="--sysroot=${STAGING_DIR}" ~~~ 然后执行`./${build_script} "buildroot" ${LICHEE_PLATFORM} ${LICHEE_CHIP}` 也就是:`./scripts/build.sh "buildroot" linux sun8iw8p1` 解析命令里没有对后面的参数进行解析。。 ~~~ case "$1" in clean) rm -rf ${LICHEE_BR_OUT} ;; *) if [ "x${LICHEE_PLATFORM}" = "xlinux" ] ; then #根本没有对这个赋值 build_buildroot export PATH=${LICHEE_BR_OUT}/external-toolchain/bin:$PATH build_external else build_toolchain fi ;; esac ~~~ 这里执行了后面的else,也就是build_toolchain(其实是解压外部工具链) ~~~ build_toolchain() { local tooldir="${LICHEE_BR_OUT}/external-toolchain" mkdir -p ${tooldir} #out/sun8iw8p1/linux/common/buildroot/external-toolchain if [ -f ${tooldir}/.installed ] ; then printf "external toolchain has been installed\n" else printf "installing external toolchain\n" printf "please wait for a few minutes ...\n" tar --strip-components=1 \ -jxf ${LICHEE_BR_DIR}/dl/gcc-linaro.tar.bz2 \ -C ${tooldir} [ $? -eq 0 ] && touch ${tooldir}/.installed fi export PATH=${tooldir}/bin:${PATH} } ~~~ 简单地说就是把buildroot/dl/gcc-linaro.tar.bz2 解压到out/sun8iw8p1/linux/common/buildroot/external-toolchain 另一路选择执行的两个函数: ~~~ build_buildroot() //编译buildroot { if [ ! -f ${LICHEE_BR_OUT}/.config ] ; then #如果没有配置过,则使用默认配置 printf "\nUsing default config ...\n\n" make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} ${LICHEE_BR_DEFCONF} fi make O=${LICHEE_BR_OUT} -C ${LICHEE_BR_DIR} LICHEE_GEN_ROOTFS=n \ BR2_JLEVEL=${LICHEE_JLEVEL} } build_external() //external-packages,指buildroot里的所有外部包 { for dir in ${EXTERNAL_DIR}/* ; do if [ -f ${dir}/Makefile ]; then BUILD_COMMAND="make -C ${dir} ${BUILD_OPTIONS} all" eval $BUILD_COMMAND BUILD_COMMAND="make -C ${dir} ${BUILD_OPTIONS} install" eval $BUILD_COMMAND fi done } ~~~ 即执行了:`make O=out/sun8iw8p1/linux/common/buildroot -C ./ LICHEE_GEN_ROOTFS=n BR2_JLEVEL=${LICHEE_JLEVEL}` 即编译br目录,但不生成rootfs ### mkkernel编译内核 ~~~ function mkkernel() { local platformdef=$tdevice if [ ! -n $tdevice ]; then echo "Please lunch device" return 1 fi echo "Make the kernel" echo "platformdef="${platformdef} (cd ${LICHEE_KERN_DIR}/; ./build.sh -p ${platformdef}) [ $? -ne 0 ] && mk_error "build mkkernel fail" && return 1 echo "Make the kernel finish" return 0 } ~~~ 执行显示结果: ~~~ Make the kernel platformdef=tiger-cdr ~~~ 即执行了:Cd lichee/linux3.4; ./build.sh -p tiger-cdr ~~~ #这里首先导入了PLATFORM=tiger-cdr while getopts hp:m: OPTION do case $OPTION in h) show_help ;; p) PLATFORM=$OPTARG ;; m) MODULE=$OPTARG ;; *) show_help ;; esac done #没有指定platform则退出 if [ -z "$PLATFORM" ]; then show_help exit 1 fi #没有指定模块则默认编译所有 if [ -z "$MODULE" ]; then MODULE="all" fi #执行scripts/build_tiger-cdr.sh if [ -x ./scripts/build_${PLATFORM}.sh ]; then ./scripts/build_${PLATFORM}.sh $MODULE else printf "\nERROR: Invalid Platform\nonly sun6i sun6i_fiber or sun6i_dragonboard sopport\n" show_help exit 1 fi ~~~ 对应目录里脚本为: ~~~ LICHEE_ROOT=`(cd ${LICHEE_KDIR}/..; pwd)` export PATH=${LICHEE_ROOT}/out/sun8iw8p1/linux/common/buildroot/external-toolchain/bin:${LICHEE_ROOT}/tools/pack/pctools/linux/android:$PATH case "$1" in kernel) build_kernel ;; modules) build_modules ;; clean) clean_kernel clean_modules ;; *) build_kernel build_modules # build_ramfs #这里可以生成boot.img # gen_output echo -e "\n\033[0;31;1m${LICHEE_CHIP} compile Kernel successful\033[0m\n\n" ;; esac ~~~ 总之就是默认编译了内核和模块。。 可以看到build_kernel其实编译了uImage和modules,并把bImage和zImage拷到了output目录 把ko文件拷到了lichee/linux-3.4/output/lib/modules/3.4.39下 ~~~ build_kernel() { echo "Building kernel" cd ${LICHEE_KDIR} rm -rf output/ echo "${LICHEE_MOD_DIR}" mkdir -p ${LICHEE_MOD_DIR} # echo "build_kernel LICHEE_KERN_DEFCONF" ${LICHEE_KERN_DEFCONF} # We need to copy rootfs files to compile kernel for linux image # cp -f rootfs.cpio.gz output/ if [ ! -f .config ] ; then # printf "\n\033[0;31;1mUsing default config ${LICHEE_KERN_DEFCONF} ...\033[0m\n\n" printf "\n\033[0;31;1mUsing default config sun8iw8p1smp_tiger_cdr_defconfig ...\033[0m\n\n" # cp arch/arm/configs/${LICHEE_KERN_DEFCONF} .config cp arch/arm/configs/sun8iw8p1smp_tiger_cdr_defconfig .config fi make ARCH=arm CROSS_COMPILE=${CROSS_COMPILE} -j${LICHEE_JLEVEL} uImage modules update_kern_ver #The Image is origin binary from vmlinux. cp -vf arch/arm/boot/Image output/bImage cp -vf arch/arm/boot/[zu]Image output/ cp .config output/ tar -jcf output/vmlinux.tar.bz2 vmlinux if [ ! -f ./drivers/arisc/binary/arisc ]; then echo "arisc" > ./drivers/arisc/binary/arisc fi cp ./drivers/arisc/binary/arisc output/ for file in $(find drivers sound crypto block fs security net -name "*.ko"); do cp $file ${LICHEE_MOD_DIR} done cp -f Module.symvers ${LICHEE_MOD_DIR} } ~~~ build_modules部分就没做事了 ### mkuboot编译uboot (这部分代码没有放出) ~~~ function mkuboot() { (cd ${LICHEE_UBOOT_DIR}; ./build.sh -p sun8iw8p1_nor) [ $? -ne 0 ] && echo "build u-boot Failed" && return 1 (cd ${LICHEE_UBOOT_DIR}; ./build.sh -p sun8iw8p1) [ $? -ne 0 ] && echo "build u-boot Failed" && return 1 return 0 } ~~~ ## extract-bsp 拷贝zimage和modules ~~~ CURDIR=$PWD cd $DEVICE #extract kernel if [ -f kernel ]; then rm kernel fi cp -rf $LICHEE_KERN_OUTDIR/zImage kernel echo "$DEVICE/zImage copied!" #extract linux modules if [ -d modules ]; then rm -rf modules fi mkdir -p modules/modules cp -rf $LINUXOUT_MODULE_DIR modules/modules echo "$DEVICE/modules copied!" chmod 0755 modules/modules/* cd $CURDIR ~~~ ## pack打包镜像 ~~~ function pack() { if [ "-d" == $1 ]; then echo "pack card" pack_card else echo "pack_normal" pack_normal fi return 0 } ~~~ ~~~ function pack_normal() { local platformdef=$tdevice echo "Pack to image........." ${platformdef} export CAMLINUX_IMAGE_OUT="$CAMLINUX_BUILD_TOP/out/target/product/${platformdef}" if [ "tiger-ipc" == ${platformdef} ]; then echo "copy tiger-ipc uboot bin files" cp -rf ${LICHEE_TOOLS_DIR}/pack/chips/sun8iw8p1/configs/tiger-ipc/bin ${LICHEE_TOOLS_DIR}/pack/chips/sun8iw8p1/ fi (cd ${LICHEE_TOOLS_DIR}/pack; ./pack -c sun8iw8p1 -p camdroid -b ${platformdef} ) [ $? -ne 0 ] && echo "pack Failed" && return 0 return 0 } function pack_card() { ... (cd ${LICHEE_TOOLS_DIR}/pack; ./pack -c sun8iw8p1 -p camdroid -b ${platformdef} -d card0 ) ... } ~~~ 打包过程: ./pack -c sun8iw8p1 -p camdroid -b ${platformdef} ~~~ do_prepare do_common echo "CAMLINUX_IMAGE_OUT="${CAMLINUX_IMAGE_OUT} do_pack_${PACK_PLATFORM} do_finish ~~~ ### do_prepare ~~~ tools_file_list=( common/tools/split_xxxx.fex chips/${PACK_CHIP}/tools/split_xxxx.fex common/tools/usbtool_test.fex chips/${PACK_CHIP}/tools/usbtool_test.fex common/tools/cardscript.fex chips/${PACK_CHIP}/tools/cardscript.fex common/tools/cardtool.fex chips/${PACK_CHIP}/tools/cardtool.fex common/tools/usbtool.fex chips/${PACK_CHIP}/tools/usbtool.fex common/tools/aultls32.fex chips/${PACK_CHIP}/tools/aultls32.fex common/tools/aultools.fex chips/${PACK_CHIP}/tools/aultools.fex ) configs_file_list=( common/toc/toc1.fex common/toc/toc0.fex common/imagecfg/image_linux.cfg common/partition/sys_partition_dump.fex common/partition/sys_partition_private.fex chips/${PACK_CHIP}/configs/default/* chips/${PACK_CHIP}/configs/${PACK_BOARD}/*.fex chips/${PACK_CHIP}/configs/${PACK_BOARD}/*.cfg ) boot_resource_list=( chips/${PACK_CHIP}/boot-resource/boot-resource:out/ chips/${PACK_CHIP}/boot-resource/boot-resource.ini:out/ chips/${PACK_CHIP}/configs/${PACK_BOARD}/bootlogo.bmp:out/boot-resource/ ) boot_file_list=( chips/${PACK_CHIP}/bin/boot0_nand_${PACK_CHIP}.bin:out/boot0_nand.fex chips/${PACK_CHIP}/bin/boot0_sdcard_${PACK_CHIP}.bin:out/boot0_sdcard.fex chips/${PACK_CHIP}/bin/boot0_spinor_${PACK_CHIP}.bin:out/boot0_spinor.fex chips/${PACK_CHIP}/bin/fes1_${PACK_CHIP}.bin:out/fes1.fex chips/${PACK_CHIP}/bin/u-boot-${PACK_CHIP}.bin:out/u-boot.fex chips/${PACK_CHIP}/bin/u-boot-spinor-${PACK_CHIP}.bin:out/u-boot-spinor.fex ) boot_file_secure=( chips/${PACK_CHIP}/bin/semelis.bin:out/semelis.bin chips/${PACK_CHIP}/bin/sboot_${PACK_CHIP}.bin:out/sboot.bin ) function do_prepare() { ... # Cleanup rm -rf out/ mkdir -p out/ printf "copying tools file\n" for file in ${tools_file_list[@]} ; do cp -f $file out/ 2> /dev/null done ... #拷贝各种fex到out下,包含开机画面等 ~~~ ### do_common 转换格式,通过fex更新boot ~~~ function do_common() { cd out/ busybox unix2dos sys_config.fex busybox unix2dos sys_partition.fex script sys_config.fex > /dev/null script sys_partition.fex > /dev/null cp -f sys_config.bin config.fex if [ "x${PACK_PLATFORM}" = "xdragonboard" ] ; then busybox dos2unix test_config.fex cp test_config.fex boot-resource/ busybox unix2dos test_config.fex script test_config.fex > /dev/null cp test_config.bin boot-resource/ fi # Those files for SpiNor. We will try to find sys_partition_nor.fex if [ -f sys_partition_nor.fex -o \ -f sys_partition_nor_${PACK_PLATFORM}.fex ]; then mv -f sys_partition_nor_${PACK_PLATFORM}.fex \ sys_partition_nor.fex >/dev/null 2>&1 # Here, will create sys_partition_nor.bin busybox unix2dos sys_partition_nor.fex script sys_partition_nor.fex > /dev/null update_boot0 boot0_spinor.fex sys_config.bin SDMMC_CARD > /dev/null update_uboot u-boot-spinor.fex sys_config.bin >/dev/null fi # Those files for Nand or Card update_boot0 boot0_nand.fex sys_config.bin NAND > /dev/null update_boot0 boot0_sdcard.fex sys_config.bin SDMMC_CARD > /dev/null update_uboot u-boot.fex sys_config.bin > /dev/null update_fes1 fes1.fex sys_config.bin > /dev/null fsbuild boot-resource.ini split_xxxx.fex > /dev/null if [ "x${PACK_FUNC}" = "xprvt" ] ; then u_boot_env_gen env_burn.cfg env.fex > /dev/null else u_boot_env_gen env.cfg env.fex > /dev/null fi if [ -f "$LICHEE_OUT/arisc" ]; then ln -s $LICHEE_OUT/arisc arisc.fex fi } ~~~ ### do_pack_${PACK_PLATFORM} ~~~ function do_pack_android() { printf "packing for android\n" if [ -z "${ANDROID_IMAGE_OUT}" ] ; then pack_error "please specify ANDROID_IMAGE_OUT env" exit 1 fi ln -s ${ANDROID_IMAGE_OUT}/boot.img boot.fex ln -s ${ANDROID_IMAGE_OUT}/system.img system.fex ln -s ${ANDROID_IMAGE_OUT}/recovery.img recovery.fex if [ -f ${ANDROID_IMAGE_OUT}/userdata.img ] ; then ln -s ${ANDROID_IMAGE_OUT}/userdata.img userdata.fex fi if [ "x${PACK_SIG}" = "xsig" ] ; then echo "signature sunxi mbr" signature sunxi_mbr.fex dlinfo.fex echo "signature over" elif [ "x${PACK_SIG}" = "xsecure" ] ; then do_signature else echo "normal" fi } function do_pack_camdroid() { printf "packing for camdroid\n" if [ -z "${CAMLINUX_IMAGE_OUT}" ] ; then pack_error "please specify CAMLINUX_IMAGE_OUT env" exit 1 fi ln -s ${CAMLINUX_IMAGE_OUT}/boot.img boot.fex ln -s ${CAMLINUX_IMAGE_OUT}/system.img rootfs.fex #使用前面打包的system.img作为根文件系统 } function do_pack_dragonboard() { printf "packing for dragonboard\n" ln -s ${LICHEE_OUT}/boot.img boot.fex ln -s ${LICHEE_OUT}/rootfs.ext4 rootfs.fex } function do_pack_linux() { printf "packing for linux\n" #输出目录是linux-3.4/output/ ln -s ${LICHEE_OUT}/vmlinux.tar.bz2 vmlinux.fex ln -s ${LICHEE_OUT}/boot.img boot.fex # ln -s ${LICHEE_OUT}/rootfs.ext4 rootfs.fex if [ "x${PACK_SIG}" = "xsecure" ] ; then do_signature else echo "normal" fi } ~~~ ### do_finish ~~~ function do_finish() { # Yeah, it should contain all files into full_img.fex for spinor # Because, as usually, spinor image size is very small. # If fail to create full_img.fex, we should fake it empty. # WTF, it is so ugly! It must be sunxi_mbr.fex, not sunxi_mbr_xxx.fex # Check whether sys_partition_nor.bin is exist, and create sunxi_mbr.fex # for Nor. if [ -f sys_partition_nor.bin ]; then mv -f sys_partition.bin sys_partition.bin_back cp -f sys_partition_nor.bin sys_partition.bin update_mbr sys_partition.bin 1 > /dev/null merge_package full_img.fex boot0_spinor.fex \ u-boot-spinor.fex sunxi_mbr.fex sys_partition.bin mv -f sys_partition.bin_back sys_partition.bin fi if [ ! -f full_img.fex ]; then echo "full_img.fex is empty" > full_img.fex fi update_mbr sys_partition_nor.bin 1 > /dev/null dragon image.cfg sys_partition_nor.fex if [ -e ${IMG_NAME} ]; then mv ${IMG_NAME} ../${IMG_NAME} echo '----------image is at----------' echo -e '\033[0;31;1m' echo ${ROOT_DIR}/${IMG_NAME} echo -e '\033[0m' fi cd .. printf "pack finish\n" } ~~~ ## 打包完成后的布局 ~~~ Device Boot Start End Blocks Id System /dev/sdf1 56992 1939454 941231+ b W95 FAT32 /dev/sdf2 * 40992 46111 2560 6 FAT16 /dev/sdf3 1 56992 28496 85 Linux extended /dev/sdf5 46112 55199 4544 83 Linux /dev/sdf6 55200 56223 512 83 Linux /dev/sdf7 56224 56479 128 83 Linux /dev/sdf8 56480 56735 128 83 Linux /dev/sdf9 56736 56863 64 83 Linux /dev/sdf10 56864 56991 64 83 Linux ~~~ 配置里的分区表: ~~~ [partition] name = boot size = 5120 downloadfile = "boot.fex" #内核ramfs [partition] name = system size = 9088 downloadfile = "rootfs.fex" #根文件系统 [partition] name = cfg size = 1024 downloadfile = "cfg.fex" #jffs2的cfg,用于保存可变的配置字段 [partition] name = boot_logo size = 256 downloadfile = "boot_logo.fex" [partition] name = shutdown_logo size = 256 downloadfile = "shutdown_logo.fex" [partition] name = env size = 128 downloadfile = "env.fex" #uboot启动的环境变量 [partition] name = private size = 128 ~~~ ### cfg.fex的生成 device/softwinner/tiger-cdr/res/make_cfg_fex.sh ~~~ CFG_PATH="/pack/chips/sun8iw8p1/configs/CDR/cfg.fex" DEST=$LICHEE_TOOLS_DIR$CFG_PATH echo "./mkfs.jffs2 -d ./data -o cfg.fex" #-p total size ./mkfs.jffs2 -d ./cfg -p 0x80000 -o cfg.fex echo "move cfg.fex to $DEST" mv cfg.fex $DEST ~~~ ### boot.fex(boot.img)生成 ~~~ INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(call pretty,"Target boot image: $@") $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw) ~~~ ~~~ regen_rootfs_cpio() { echo "regenerate rootfs cpio" cd ${LICHEE_KDIR}/output echo "###" if [ -x "../scripts/build_rootfs.sh" ]; then ../scripts/build_rootfs.sh e ./rootfs.cpio.gz > /dev/null else echo "No such file: scripts/build_rootfs.sh" exit 1 fi echo "###" mkdir -p ./skel/lib/modules/${KERNEL_VERSION} echo "###" if [ -e ${LICHEE_MOD_DIR}/nand.ko ]; then cp ${LICHEE_MOD_DIR}/nand.ko ./skel/lib/modules/${KERNEL_VERSION} if [ $? -ne 0 ]; then echo "copy nand module error: $?" exit 1 fi fi echo "###ttt" ko_file=`find ./skel/lib/modules/$KERNEL_VERSION/ -name *.ko` if [ ! -z "$ko_file" ]; then ${STRIP} -d ./skel/lib/modules/$KERNEL_VERSION/*.ko fi echo "###ttt" rm -f rootfs.cpio.gz ../scripts/build_rootfs.sh c rootfs.cpio.gz > /dev/null rm -rf skel echo "###ttt" cd - > /dev/null } ~~~ TARGET_ROOT_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_ROOT) # 修改配置生成linux镜像 由上面的走读可知,需要生成boot分区,linux根文件系统分区,及对应的分区表 内核配置: linux-3.4/arch/arm/configs/sun8iw8p1smp_defconfig linux-3.4/arch/arm/configs/sun8iw8p1smp_tiger_cdr_defconfig 配置内核: make ARCH=arm menuconfig 板级配置和开机logo ls tools/pack/chips/sun8iw8p1/configs/tiger-cdr/ boot-resource cfg.fex sys_config.fex sys_partition_nor_camdroid.fex
';

Zero Linux系统适配过程记录

最后更新于:2022-04-01 23:27:20

';

安卓ROM深度定制

最后更新于:2022-04-01 23:27:17

';

uart适配

最后更新于:2022-04-01 23:27:15

# UART适配 ## linux 下适配 使用默认编译的安卓系统,ls /dev可以看到 ttyS0~3 尝试echo 'test' > /dev/ttyS0 可以在串口终端看到test字符,说明uart1就是ttyS0 荔枝派上除了默认的uart1是系统log输出口外,uart0与sdc0复用,不方便使用,就剩uart3可以使用。 linux下使用stty设置串口参数: `stty -F /dev/ttyS1 ispeed 115200 ospeed 115200` 但是发现对ttyS0之外的串口操作会返回:`stty: /dev/ttyS1: Input/output error` 在linux的驱动目录下找到相关文件:tty/serial/8250_sunxi.c ~~~ struct platform_device sw_uart_dev[] = { [0] = {.name = "sunxi-uart", .id = 0, .num_resources = ARRAY_SIZE(sw_uart_res[0]), .resource = &sw_uart_res[0][0], .dev = {}}, ...... }; static int __init sw_serial_init(void) { int ret; int i; int used = 0; char uart_para[16]; memset(sw_serial, 0, sizeof(sw_serial)); uart_used = 0; for (i=0; iport_no = dev->id; sport->pdev = dev; ret = sw_serial_get_config(sport, dev->id); if (ret) { UART_MSG(KERN_ERR "Failed to get config information\n"); goto free_dev; } ret = sw_serial_get_resource(sport); if (ret) { UART_MSG(KERN_ERR "Failed to get resource\n"); goto free_dev; } platform_set_drvdata(dev, sport); sport->port.irq = sport->irq; sport->port.fifosize= 64; sport->port.regshift= 2; sport->port.iotype = UPIO_DWAPB32; sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; sport->port.uartclk = sport->sclk; sport->port.pm = sw_serial_pm; sport->port.dev = &dev->dev; sport->port.mapbase = sport->mmres->start; sw_serial[sport->port_no] = serial8250_register_port(&sport->port); //注册端口 UART_MSG("serial probe %d, membase %p irq %d mapbase 0x%08x\n", dev->id, sport->port.membase, sport->port.irq, sport->port.mapbase); UART_MSG("sport->pdev is %x \n &sport->pdev is %x",sport->pdev,&sport->pdev); UART_MSG("pdev.dev is %x \n &pdev.dev is %x",sport->pdev->dev,&sport->pdev->dev); UART_MSG("dev.dev is %x \n &dev.dev is %x",dev->dev,&dev->dev); return 0; free_dev: kfree(sport); sport = NULL; return ret; } ~~~ .config ~~~ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_SUNXI=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 ~~~ 8250.c ~~~ #define UART_NR CONFIG_SERIAL_8250_NR_UA RTS static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; int serial8250_register_port(struct uart_port *port) { struct uart_8250_port *uart; int ret = -ENOSPC; if (port->uartclk == 0) return -EINVAL; mutex_lock(&serial_mutex); uart = serial8250_find_match_or_unused(port); if (uart) { uart_remove_one_port(&serial8250_reg, &uart->port); uart->port.iobase = port->iobase; uart->port.membase = port->membase; uart->port.irq = port->irq; uart->port.irqflags = port->irqflags; uart->port.uartclk = port->uartclk; uart->port.fifosize = port->fifosize; uart->port.regshift = port->regshift; uart->port.iotype = port->iotype; uart->port.flags = port->flags | UPF_BOOT_AUTOCONF; uart->port.mapbase = port->mapbase; uart->port.private_data = port->private_data; if (port->dev) uart->port.dev = port->dev; if (port->flags & UPF_FIXED_TYPE) serial8250_init_fixed_type_port(uart, port->type); set_io_from_upio(&uart->port); /* Possibly override default I/O functions. */ uart->port.flags = port->flags | UPF_BOOT_AUTOCONF; uart->port.mapbase = port->mapbase; uart->port.private_data = port->private_data; if (port->dev) uart->port.dev = port->dev; if (port->flags & UPF_FIXED_TYPE) serial8250_init_fixed_type_port(uart, port->type); set_io_from_upio(&uart->port); /* Possibly override default I/O functions. */ if (port->serial_in) uart->port.serial_in = port->serial_in; if (port->serial_out) uart->port.serial_out = port->serial_out; /* Possibly override set_termios call */ if (port->set_termios) uart->port.set_termios = port->set_termios; if (port->pm) uart->port.pm = port->pm; if (serial8250_isa_config != NULL) serial8250_isa_config(0, &uart->port, &uart->capabilities); ret = uart_add_one_port(&serial8250_reg, &uart->port); if (ret == 0) ret = uart->port.line; } mutex_unlock(&serial_mutex); return ret; } ~~~ serial_core.c ~~~ /** * uart_add_one_port - attach a driver-defined port structure * @drv: pointer to the uart low level driver structure for this port * @uport: uart port structure to use for this port. * * This allows the driver to register its own uart_port structure * with the core driver. The main purpose is to allow the low * level uart drivers to expand uart_port, rather than having yet * more levels of structures. */ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) { struct uart_state *state; struct tty_port *port; int ret = 0; struct device *tty_dev; BUG_ON(in_interrupt()); if (uport->line >= drv->nr) return -EINVAL; state = drv->state + uport->line; port = &state->port; mutex_lock(&port_mutex); mutex_lock(&port->mutex); if (state->uart_port) { ret = -EINVAL; goto out; } state->uart_port = uport; state->pm_state = -1; uport->cons = drv->cons; uport->state = state; /* * If this port is a console, then the spinlock is already * initialised. */ if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) { spin_lock_init(&uport->lock); lockdep_set_class(&uport->lock, &port_lock_key); } uart_configure_port(drv, state, uport); /* * Register the port whether it's detected or not. This allows * setserial to be used to alter this ports parameters. */ tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); //最终注册设备 if (likely(!IS_ERR(tty_dev))) { device_init_wakeup(tty_dev, 1); device_set_wakeup_enable(tty_dev, 0); } else printk(KERN_ERR "Cannot register tty device on line %d\n", uport->line); /* * Ensure UPF_DEAD is not set. */ uport->flags &= ~UPF_DEAD; out: mutex_unlock(&port->mutex); mutex_unlock(&port_mutex); return ret; } ~~~ tty_io.c ~~~ struct device *tty_register_device(struct tty_driver *driver, unsigned index, struct device *device) { char name[64]; dev_t dev = MKDEV(driver->major, driver->minor_start) + index; if (index >= driver->num) { printk(KERN_ERR "Attempt to register invalid tty line number " " (%d).\n", index); return ERR_PTR(-EINVAL); } if (driver->type == TTY_DRIVER_TYPE_PTY) pty_line_name(driver, index, name); else tty_line_name(driver, index, name); return device_create(tty_class, device, dev, NULL, name); } EXPORT_SYMBOL(tty_register_device); static void tty_line_name(struct tty_driver *driver, int index, char *p) { sprintf(p, "%s%d", driver->name, index + driver->name_base); //最终的ttySx } ~~~ 大致的驱动加载过程就是上面这样 下面看下log信息: ~~~ [ 0.158533] [uart]: used uart info.: 0x06 [ 0.158563] [uart]: this coming sw_serial_probe [ 0.288179] [uart]: serial probe 1, membase (null) irq 2 mapbase 0x01c28400 [ 0.295378] [uart]: sport->pdev is c08c4a08 [ 0.295383] &sport->pdev is df04c2c8[uart]: pdev.dev is c08c4ad0 [ 0.303155] &pdev.dev is c08c5680[uart]: dev.dev is c08c4ad0 [ 0.309079] &dev.dev is c08c5680[uart]: this coming sw_serial_probe [ 0.318097] [uart]: <3>Failed to get config information [ 0.323344] sunxi-uart: probe of sunxi-uart.2 failed with error -1 ~~~ 可见uart1和uart3在获取fex时都被识别出来了,uart1成功probe,但是uart3“Failed to get config information” uart3对应sw_uart_dev[2],即 ~~~ ret = sw_serial_get_config(sport, dev->id); if (ret) { UART_MSG(KERN_ERR "Failed to get config information\n"); goto free_dev; } static int sw_serial_get_config(struct sw_serial_port *sport, u32 uart_id) { char uart_para[16] = {0}; int ret; sprintf(uart_para, "uart_para%d", uart_id); ret = script_parser_fetch(uart_para, "uart_port", &sport->port_no, sizeof(int)); if (ret) return -1; if (sport->port_no != uart_id) return -1; ret = script_parser_fetch(uart_para, "uart_type", &sport->pin_num, sizeof(int)); if (ret) return -1; return 0; } ~~~ 查看可知fex里的uart_port和uart_parax必须一一对应,所以就是fex里之前写错了,改正回来 这时查看ttyS1参数就有了: ~~~ busybox stty -F /dev/ttyS1 speed 9600 baud; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -brkint -imaxbel ~~~ 设置下波特率,并测试 ~~~ busybox stty -F /dev/ttyS1 ispeed 115200 ospeed 115200 echo 'test' > /dev/ttyS1 ~~~ 成功在uart3上收到数据~
';

pm解析

最后更新于:2022-04-01 23:27:13

';

usb适配

最后更新于:2022-04-01 23:27:11

# usb适配简记 ##usb调试信息太多,删减之 ~~~ [ 232.061924] [sw_hcd]: sw_hcd_urb_dequeue, sw_hcd(df8a28ec, 0x0, 0x3f),urb(dbd34f00, 1514, 0), dev = 3, ep = 2, dir = in [ 232.071179] sw_hcd_cleanup_urb: qh(0xd0df6e40,0x2,0x2), urb(0xdbd34f00,1514,0), ep(0xdf8a2a00,3,0xd0df6e40,0x (null)) ~~~ 出处在 ~~~ ./linux-3.0/drivers/usb/sun5i_usb/hcd/core/sw_hcd_host.c: DMSG_INFO("[sw_hcd]: sw_hcd_urb_dequeue, sw_hcd(%p, 0x%d, 0x%x)," ./linux-3.0/drivers/usb/sun5i_usb/hcd/core/sw_hcd_host.c: DMSG_INFO("sw_hcd_cleanup_urb: qh(0x%p,0x%x,0x%x), urb(0x%p,%d,%d), ep(0x%p,%d,0x%p,0x%p)\n", ~~~ 修改linux-3.0/drivers/usb/sun5i_usb/include/sw_usb_debug.h ~~~ /* 普通信息打印 */ #if 0 #define DMSG_INFO DMSG_PRINT #else #define DMSG_INFO(...) #endif ~~~ ##3g网卡适配 安卓下开启3g网卡主要步骤是 1. 在驱动中勾选usb串口,pppd等 2. 调试通过usb_modeswitch, 模式切换后自动或者手动出现3个ttyUSBx设备 3. evdo脚本拨号 4. ###在内核配置里开启串口驱动,pppd驱动等 `Device Drivers -> USB support -> USB Serial Converter support USB driver for GSM and CDMA modems` ~~~ <*> PPP (point-to-point protocol) support [*] PPP multilink support (EXPERIMENTAL) [*] PPP filtering <*> PPP support for async serial ports <*> PPP support for sync tty ports <*> PPP Deflate compression <*> PPP BSD-Compress compression <*> PPP MPPE compression (encryption) (EXPERIMENTAL) <*> PPP over Ethernet (EXPERIMENTAL) <*> PPP over IPv4 (PPTP) (EXPERIMENTAL) <*> PPP over L2TP (EXPERIMENTAL) <*> PPP on L2TP Access Concentrator <*> PPP on PPTP Network Server ~~~ ###先在电脑上试着驱动3g网卡 : 插上后查看内核信息: ~~~ [ 8497.458906] usb 2-2.1: new full-speed USB device number 12 using uhci_hcd [ 8497.726318] usb 2-2.1: New USB device found, idVendor=1d09, idProduct=1000 [ 8497.726323] usb 2-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 8497.726325] usb 2-2.1: Product: USB MMC Storage [ 8497.726327] usb 2-2.1: Manufacturer: Qualcomm, Incorporated [ 8497.726329] usb 2-2.1: SerialNumber: 000000000002 [ 8497.729026] usb-storage 2-2.1:1.0: USB Mass Storage device detected [ 8497.729192] scsi host43: usb-storage 2-2.1:1.0 [ 8498.732291] scsi 43:0:0:0: Direct-Access Qualcomm MMC Storage 2.31 PQ: 0 ANSI: 2 [ 8498.738204] scsi 43:0:0:1: CD-ROM Qualcomm MMC Storage 2.31 PQ: 0 ANSI: 2 [ 8498.741198] sd 43:0:0:0: Attached scsi generic sg3 type 0 [ 8498.835612] sd 43:0:0:0: [sdb] Attached SCSI removable disk [ 8500.089041] sr 43:0:0:1: [sr2] scsi3-mmc drive: 357x/308x writer cdda [ 8500.089184] sr 43:0:0:1: Attached scsi CD-ROM sr2 [ 8500.089287] sr 43:0:0:1: Attached scsi generic sg4 type 5 [ 8500.361385] sr 43:0:0:1: [sr2] CDROM (ioctl) error, command: [ 8500.361391] Xpwrite, Read disk info 51 00 00 00 00 00 00 00 02 00 [ 8500.361395] sr 43:0:0:1: [sr2] Sense Key : Hardware Error [current] [ 8500.361397] sr 43:0:0:1: [sr2] Add. Sense: No additional sense information ~~~ lsusb看网卡型号: > Bus 002 Device 007: ID 1d09:1000 TechFaith Wireless Technology Limited 可以看到被识别成了安装光盘,sr2,手动弹出光盘后就变为正常的设备: eject sr2 //有些网卡需要发送特别的指令,需要使用usb_modeswitch切换模式 > Bus 002 Device 013: ID 1d09:e003 TechFaith Wireless Technology Limited 这就和usb_modeswitch的效果一样 ~~~ [ 8662.455084] usb 2-2.1: USB disconnect, device number 12 [ 8666.948103] usb 2-2.1: new full-speed USB device number 13 using uhci_hcd [ 8667.220302] usb 2-2.1: New USB device found, idVendor=1d09, idProduct=e003 [ 8667.220305] usb 2-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=4 [ 8667.220307] usb 2-2.1: Product: CDMA 1x/EVDO Rev.A Device [ 8667.220309] usb 2-2.1: Manufacturer: Co.,Ltd [ 8667.220310] usb 2-2.1: SerialNumber: 000000000002 [ 8667.240512] usb-storage 2-2.1:1.3: USB Mass Storage device detected [ 8667.246943] scsi host44: usb-storage 2-2.1:1.3 [ 8668.253167] scsi 44:0:0:0: Direct-Access Qualcomm MMC Storage 2.31 PQ: 0 ANSI: 2 [ 8668.255704] sd 44:0:0:0: Attached scsi generic sg3 type 0 [ 8668.271240] sd 44:0:0:0: [sdb] Attached SCSI removable disk ~~~ PID=0x1D09, VID=0xe0003 在drivers/usb/serial/option.c里加入PID,VID(转换后的) ~~~ //发现华为一个型号的PID一样。。 #define HUAWEI_PRODUCT_ET128 0x1D09 #define HUAWEI_VENDOR_ID 0x12D1 //自己加一个吧 595 static const struct usb_device_id option_ids[] = { 596 { USB_DEVICE(0xe0003, 0x1d09) }, //ID 1d09:1000 TechFaith Wireless Technology Limited ~~~ Device Monitoring Studio抓取3G网卡MessageContent http://blog.chinaunix.net/uid-29764914-id-5181529.html usb_modeswitch的使用(新版下的规则文件下载) http://blog.csdn.net/yang1982_0907/article/details/45969179 但是切换后仍然没有ttyUSBx, 需要手工增加: ~~~ modprobe usb_wwan modprobe option echo "1d09 e003" > /sys/bus/usb-serial/drivers/option1/new_id ~~~ 运行后出现了ttyUSB0~2 可以将它加入到udev规则中,在/lib/udev/rules.d/50-udev-default.rules(也可能再etc目录中)后面添加 ACTION=="add", SUBSYSTEM=="usb",SYSFS{idVendor}=="1d09", SYSFS{idProduct}=="1000", RUN+="/usr/sbin/usb_modeswitch -c /etc/usb_modeswitch.conf" RUN+="echo '1d09 e003' > /sys/bus/usb-serial/drivers/option1/new_id" //安卓下已经自带 ~~~ vim /etc/usb_modeswitch.d/1d09_1000 DefaultVendor= 0x1d09 DefaultProduct= 0x1000 TargetVendor= 0x1d09 TargetProduct= 0xe003 StandardEject=1 CheckSuccess= 10 #wait 10s ~~~ 然后进行拨号,在/etc/ppp/peers目录下创建新文件evdo: ~~~ mkdir /etc/ppp/peers/ busybox vi /etc/ppp/peers/evdo ~~~ ~~~ /dev/ttyUSB0 115200 nodetach lock user "ctnet@mycdma.cn" password "vnet.mobi" crtscts show-password usepeerdns noauth noipdefault novj novjccomp noccp defaultroute ipcp-accept-local ipcp-accept-remote connect '/usr/sbin/chat -s -v -f /etc/ppp/peers/evdo-connect-chat' #connect '/system/bin/chat -s -v -f /etc/ppp/peers/evdo-connect-chat' #android ~~~ 再创建evdo-connect-chat `busybox vi /etc/ppp/peers/evdo-connect-chat` ~~~ TIMEOUT 2 ABORT 'NO CARRIER' ABORT 'ERROR' ABORT 'NO DIALTONE' ABORT 'BUSY' ABORT 'NO ANSWER' "" ATE1 "" "AT+CFUN=1" OK-AT-OK ATD#777 CONNECT '' ~~~ 输入命令pppd call evdo&就可以上网了,断开网络就输入poff。 输出的拨号信息: ~~~ pppd call evdo timeout set to 2 seconds abort on (NO CARRIER) abort on (ERROR) abort on (NO DIALTONE) abort on (BUSY) abort on (NO ANSWER) send (ATE1^M) send (AT+CFUN=1^M) expect (OK) ^M OK -- got it send (ATD#777^M) expect (CONNECT) ^M AT+CFUN=1^M^M OK^M ATD#777^M^M CONNECT -- got it send (^M) Serial connection established. Using interface ppp0 Connect: ppp0 <--> /dev/ttyUSB0 CHAP authentication succeeded: OK CHAP authentication succeeded local IP address 10.100.35.16 remote IP address 125.88.103.85 primary DNS address 114.114.114.114 secondary DNS address 223.5.5.5 ^CTerminating on signal 2 Connect time 0.2 minutes. Sent 355 bytes, received 126 bytes. Connection terminated. ~~~ ###安卓上驱动 安卓上串口和dmesg的信息有限,主要看logcat 首次尝试pppd call evdo,log信息如下: `pppd ( 1230): Can't create lock file /var/lock/LCK..ttyUSB0` 排查发现根本没有/var/lock目录,于是新建/var/run和/var/lock目录 ~~~ mkdir /var mkdir /var/run mkdir /var/lock ~~~ 重新拨号,dmesg提示: ~~~ timeout set to 2 seconds abort on (NO CARRIER) abort on (ERROR) abort on (NO DIALTONE) abort on (BUSY) abort on (NO ANSWER) send (ATE1^M) send (AT+CFUN=1^M) expect (OK) ATE1^M^M OK -- got it send (ATD#777^M) expect (CONNECT) ^M AT+CFUN=1^M^M OK^M ATD#777^M^M CONNECT -- got it send (^M) ~~~ logcat -v time提示 ~~~ 01-02 08:01:51.419 I/pppd ( 1195): Serial connection established. 01-02 08:01:51.429 D/pppd ( 1195): using channel 1 01-02 08:01:51.479 I/pppd ( 1195): Using interface ppp0 01-02 08:01:51.479 I/pppd ( 1195): Connect: ppp0 <--> /dev/ttyUSB0 01-02 08:01:52.179 I/pppd ( 1195): CHAP authentication succeeded: OK 01-02 08:01:52.299 I/pppd ( 1195): local IP address 10.100.34.51 01-02 08:01:52.299 I/pppd ( 1195): remote IP address 125.88.103.85 01-02 08:01:52.299 I/pppd ( 1195): primary DNS address 114.114.114.114 01-02 08:01:52.299 I/pppd ( 1195): secondary DNS address 223.5.5.5 ~~~ ifconfig可见ppp0设备: ~~~ ppp0 Link encap:Point-to-Point Protocol inet addr:10.100.46.132 P-t-P:125.88.103.85 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1430 Metric:1 RX packets:3 errors:0 dropped:0 overruns:0 frame:0 TX packets:3 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:54 (54.0 B) TX bytes:54 (54.0 B) ~~~ 此时已经可以ping 通114.114.114.114,但无法解析域名 ~~~ busybox vi init.sun5i.rc setprop "net.dns1" "8.8.8.8" setprop "net.dns2" "8.8.4.4" ~~~ ###安卓上3g网卡自动加载总结 0. 切换上网卡状态(/etc/usb_modeswitch.d/1d09_1000自动完成) 1. 创建ttyUSB0等串口 `echo "1d09 e003" > /sys/bus/usb-serial/drivers/option1/new_id` 2. /etc/ppp/peers/evdo /etc/ppp/peers/evdo-connect-chat 拨号脚本(创建一次即可) 3. mkdir /var /var/run /var/lock 创建临时目录 4. pppd call evdo& 拨号上网,并设置dns 0,已经自动完成 1,需要在init.sun5i.rc里加上初始化 ~~~ on boot #echo "1d09 e003" > /sys/bus/usb-serial/drivers/option1/new_id //太早执行无效 exec /system/bin/sh /system/etc/ppp.sh //这里延时到开机执行 ~~~ 2, 在sdk里加上对应的脚本 相关文件在device/softwinner/common/rild里,需要修改上层的sw-common.mk来拷贝文件到system分区 ~~~ PRODUCT_COPY_FILES += \ device/softwinner/common/rild/ip-down:system/etc/ppp/ip-down \ device/softwinner/common/rild/ip-up:system/etc/ppp/ip-up \ device/softwinner/common/rild/call-pppd:system/etc/ppp/call-pppd \ device/softwinner/common/rild/peers/evdo:system/etc/ppp/peers/evdo\ device/softwinner/common/rild/peers/evdo-connect-chat:system/etc/ppp/peers/evdo-connect-chat\ ~~~ 3, 需要在init.sun5i.rc里加上初始化 ~~~ mkdir /var 0770 root system mount tmpfs none /var mode=0770,uid=0,gid=1000 mkdir /var/run 0750 root system mkdir /var/lock 0750 root system ~~~ 4, 需要在init.sun5i.rc里加上初始化 ~~~ service ppp /system/bin/pppd call evdo user root group system radio disabled oneshot setprop "net.dns1" "8.8.8.8" setprop "net.dns2" "8.8.4.4" ~~~
';

wifi适配

最后更新于:2022-04-01 23:27:08

# RTL8723BU wifi模块适配 ##linux驱动添加 安卓下使能外设驱动都需要先适配好linux下驱动,所以首先来编译linux驱动模块 1. 拷贝官方驱动(github的资源文件目录下下载)到lichee的linux驱动目录下 ~~~ zp@ubuntu:~/develop/a13_android4.1_v1.2/lichee$ ls linux-3.0/drivers/net/wireless/rtl8723bu/ clean core hal ifcfg-wlan0 include Kconfig Makefile os_dep platform runwpa wlan0dhcp ~~~ 2. 配置驱动Makefile以及Kconfig,然后在menuconfig里选中刚加入的驱动 `CONFIG_PLATFORM_ARM_SUNxI = y` `obj-$(CONFIG_RTL8723BU) += rtl8723bu/` `source "drivers/net/wireless/rtl8723bu/Kconfig"` ` Realtek 8723B USB WiFi` 3. 重新编译lichee,获得内核模块 `./build.sh -p a13_nuclear -k 3.0` ~~~ zp@ubuntu:~/develop/a13_android4.1_v1.2/lichee$ ls out/android/lib/modules/3.0.8+/87* out/android/lib/modules/3.0.8+/8723bu.ko ~~~ 4. 修改wifi驱动,隐藏过多调试信息 前面这样生成的ko带有很多调试信息输出,以至于开启wifi模块时太慢,导致打开wifi超时,所以需要隐藏多余的信息。 编辑linux-3.0/drivers/net/wireless/rtl8723bu/include/autoconf.h,去掉DEBUG的相关宏定义。 ##安卓配置文件 1. 修改板级配置文件device/softwinner/nuclear-evb/BoardConfig.mk ~~~ BOARD_WIFI_VENDOR := realtek ifeq ($(BOARD_WIFI_VENDOR), realtek) WPA_SUPPLICANT_VERSION := VER_0_8_X BOARD_WPA_SUPPLICANT_DRIVER := NL80211 BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_rtl BOARD_HOSTAPD_DRIVER := NL80211 BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_rtl SW_BOARD_USR_WIFI := rtl8723bu BOARD_WLAN_DEVICE := rtl8723bu endif ~~~ 2. 修改init启动脚本init.sun5i.rc ~~~ # 1.1 realtek wifi sta service service wpa_supplicant /system/bin/wpa_supplicant -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -e/data/misc/wifi/entropy.bin class main socket wpa_wlan0 dgram 660 wifi wifi disabled oneshot # 1.2 realtek wifi sta p2p concurrent service service p2p_supplicant /system/bin/wpa_supplicant \ -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf -e/data/misc/wifi/entropy.bin -N \ -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf class main socket wpa_wlan0 dgram 660 wifi wifi disabled oneshot ~~~ 3.修改安卓板级mk文件nuclear_evb.mk(蓝牙需要,wifi不用改) 4. 修改安卓hardware相关代码hardware/libhardware_legacy/wifi/wifi.c ~~~ #elif defined RTL_8723BU_WIFI_USED /* rtl8723bu usb wifi */ #ifndef WIFI_DRIVER_MODULE_PATH #define WIFI_DRIVER_MODULE_PATH "/system/vendor/modules/8723bu.ko" #endif #ifndef WIFI_DRIVER_MODULE_NAME #define WIFI_DRIVER_MODULE_NAME "8723bu" #endif #ifndef WIFI_DRIVER_MODULE_ARG #define WIFI_DRIVER_MODULE_ARG "ifname=wlan0 if2name=p2p0" ~~~ 5. wifi的安卓mk修改 ~~~ hardware/libhardware_legacy/wifi/Android.mk ifeq ($(SW_BOARD_USR_WIFI), rtl8723bu) LOCAL_CFLAGS += -DRTL_8723BU_WIFI_USED LOCAL_CFLAGS += -DRTL_WIFI_VENDOR endif ~~~ 6. wpa的安卓mk修改 ~~~ external/wpa_supplicant_8/wpa_supplicant/Android.mk ifeq ($(SW_BOARD_USR_WIFI), rtl8188eu) L_CFLAGS += -DCONFIG_WFD endif ~~~ 5. 重新编译安卓 实际需要更新的就只有libhardware_legacy.so和8723bu.ko,当然也可以打包整个镜像重新烧写。 以局部更新为例,挂载tf卡的第7分区,拷贝so到lib/libhardware_legacy.so 拷贝ko到vendor/modules sync后启动即可
';

codec适配及Audio系统解析

最后更新于:2022-04-01 23:27:06

# codec适配及Audio系统解析 ##codec适配 启动后耳机及mic无反应,开始绕了个大圈看了遍安卓的Audio系统,结果从最上层查到最底层,发现原因不过是fex没写全而已: ~~~ [audio_para] audio_used = 1 audio_playback_used = 1 capture_used = 1 audio_lr_change = 0 audio_pa_ctrl = port:PG0<1><0> ~~~ 加上audio_pa_ctrl的配置即可,这里使用了空闲引脚PG0,实际上没有接PA,也可以直接改驱动源码来支持不接PA,不过比较麻烦,就直接拿个空闲引脚凑数了。 ##Audio系统解析
';

安卓下外设适配及其系统解析

最后更新于:2022-04-01 23:27:04

';

安卓系统架构解析

最后更新于:2022-04-01 23:27:02

';

安卓编译系统解析

最后更新于:2022-04-01 23:26:59

#安卓编译简记 qq群里 @随风破浪 编译安卓一星期未果,我之前的开发机上的lichee目录又不小心被覆盖了,所以抽空简单记录下如何在原始sdk的基础上 修改适配,成功编译出可以跑在荔枝派上的安卓系统。 ##1. 编译环境准备 ### 开发机系统要求 编译安卓需要64位linux系统,推荐**ubuntu 1404**或者**1604**, 开发机至少需要**4GB内存,40GB硬盘**;推荐**8GB内存,100GB硬盘**以上。 以下是开发过程中目录大小示意: ~~~ zp@ubuntu:~/develop$ du -lh --max-depth=1 v1.5.0/ 26G v1.5.0/android 6.8G v1.5.0/lichee 33G v1.5.0/ zp@ubuntu:~/develop$ du -lh --max-depth=1 a13_android4.1_v1.2/ 5.2G a13_android4.1_v1.2/lichee 23G a13_android4.1_v1.2/android4.1 28G a13_android4.1_v1.2/ ~~~ 开发机的CPU配置尽量高,笔者12线程并行编译,配以ssd,首次编译需要45分钟 网友双线程编译,耗时4小时左右。 ### 开发机软件环境 首先安装开发所需要的软件包和一些库。 下面的一些安装包可能有些过时的,遇到版本问题请自行解决。 在线安装 JDK6.0 ~~~ sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner" sudo add-apt-repository ppa:ferramroberto/java sudo apt-get update sudo apt-get install sun-java6-jdk sudo update-alternatives --c onfig java ~~~ 在线安装编译库 ~~~ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev g++-multilib mingw32 tofrodos python-markdown libxml2-utils ~~~ ### SDK下载 > 链接: http://pan.baidu.com/s/1pLnjfoZ 密码: cvnm 在SDK目录下 下载以下两个文件 ~~~ lichee-4.1-v1.2.tar.gz android4.1-v1.2.tar.gz ~~~ 这是安卓4.1的SDK,前面的是4.2的SDK, > 我手上的4.2 SDK的mali驱动ko和应用层库so版本对不上,换了从4.1里抠出的对应版本的so后,可以勉强启动系统,但是会不定时地出现缓冲队列满的问题导致ANR,所以暂时无法使用 在开发机上新建目录,如a13_android4.1 然后把两个sdk拷入,解压 把lichee对应的目录名改成lichee(即去掉版本号),目录如下所示 ~~~ zp@ubuntu:~/develop/a13_android4.1_v1.2$ ls android4.1 lichee ~~~ ##2. lichee编译 lichee是安卓系统的linux内核部分,需要首先编译,进入lichee目录执行: ~~~ ./build.sh -p a13_nuclear -k 3.0 ./build.sh pack ~~~ ### 编译错误解析 编译过程中会出错,每个人由于其开发环境以及执行步骤的不同,错误都可能不同,下面以我编译时遇到的错误为例进行解析 1. mali驱动编译出错 ~~~ make: Entering directory `/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali' /home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0 make -C DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump CONFIG=ca8-virtex820-m400-1 BUILD=release KDIR=/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0 make[1]: Entering directory `/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali/DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump' make -C /home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0 M=/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali/DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump modules make[2]: Entering directory `/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0' CC [M] /home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali/DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump/common/ump_kernel_common.o arm-none-linux-gnueabi-gcc: directory: No such file or directory arm-none-linux-gnueabi-gcc: directory": No such file or directory :0:16: warning: missing terminating " character make[3]: *** [/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali/DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump/common/ump_kernel_common.o] Error 1 make[2]: *** [_module_/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali/DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump] Error 2 make[2]: Leaving directory `/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0' make[1]: *** [all] Error 2 make[1]: Leaving directory `/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali/DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump' make: *** [build] Error 2 make: Leaving directory `/home/zp/develop/a13_android4.1_v1.2/lichee/linux-3.0/modules/mali' real 2m35.400s user 15m36.416s sys 0m35.740s ~~~ 进入排除可知是脚本里检查了SVN版本的问题,我们直接忽略SVN版本,将linux-3.0/modules/mali/DX910-SW-99002-r3p1-01rel0/driver/src/devicedrv/ump 目录下的SVN_REV直接赋值为0(在Kbuild和Makefile.common中) 重新编译,仍然是类似的错误,只是换了个目录,于是直接在mali驱动目录下全局搜索SVN_REV,将赋值的地方直接改为0 再重新编译成功 ~~~ mkdir: created directory ‘/home/zp/develop/a13_android4.1_v1.2/lichee/out’ ‘/home/zp/develop/a13_android4.1_v1.2/lichee/u-boot/u-boot.bin’ -> ‘/home/zp/develop/a13_android4.1_v1.2/lichee/out/android/u-boot.bin’ ############################### # compile success # ############################### real 0m51.177s user 1m1.324s sys 0m4.736s ~~~ ##3. 安卓编译 进入安卓目录,执行以下命令序列: ~~~ source build/envsetup.sh #导入一些环境变量 lunch #选择板型,直接选择10. nuclear_evb-eng,以后也直接在上面改 extract-bsp #将lichee中编译得到的内核镜像和模块拷贝过来 time make -j12 2>&1 | tee log.txt #编译system.img,这里-j12换成你电脑的线程数(核数*2)。12线程耗时约 pack #打包成刷机镜像 ~~~ 编译system.img成功的提示: ~~~ Creating filesystem with parameters: Size: 536870912 Block size: 4096 Blocks per group: 32768 Inodes per group: 8192 Inode size: 256 Journal blocks: 2048 Label: Blocks: 131072 Block groups: 4 Reserved block group size: 31 Created filesystem with 1443/32768 inodes and 102168/131072 blocks + '[' 0 -ne 0 ']' Running: mkuserimg.sh -s out/target/product/nuclear-evb/system out/target/product/nuclear-evb/obj/PACKAGING/systemimage_intermediates/system.img ext4 system 536870912 Install system fs image: out/target/product/nuclear-evb/system.img out/target/product/nuclear-evb/system.img+out/target/product/nuclear-evb/obj/PACKAGING/recovery_patch_intermediates/recovery_from_boot.p maxsize=548110464 blocksize=4224 total=412271984 reserve=5537664 real 36m1.948s user 350m4.772s sys 14m16.936s ~~~ pack打包成功的提示: ~~~ /home/zp/develop/a13_android4.1_v1.2/lichee/tools/pack/pctools/linux/eDragonEx//home/zp/develop/a13_android4.1_v1.2/lichee/tools/pack/outBuildImg 0 Dragon execute image.cfg SUCCESS ! CPlugin Free lib CPlugin Free lib ---------image is at------------- /home/zp/develop/a13_android4.1_v1.2/lichee/tools/pack/sun5i_android_a13-evb.img ~~~ ### 编译错误解析 1. 注意如果编译时突然中断,则可能出现文件截断的情况,需要先清空out 下子目录中的的obj目录,才好继续编译 例如下面错误就是: ~~~ target thumb C++: camera. <= device/softwinner/common/hardware/camera/HALCameraFactory.cpp In file included from device/softwinner/common/hardware/camera/CameraHardwareDevice.h:26:0, from device/softwinner/common/hardware/camera/HALCameraFactory.cpp:30: device/softwinner/common/hardware/camera/CameraHardware.h:29:23: fatal error: videodev2.h: No such file or directory compilation terminated. make: *** [out/target/product/generic/obj/SHARED_LIBRARIES/camera._intermediates/HALCameraFactory.o] Error 1 make: *** Waiting for unfinished jobs.... ~~~ 2. 在pack时遇到以下错误(虽然不导致编译失败,但是启动时会造成错误) ~~~ fail:/home/zp/develop/a13_android4.1_v1.2/lichee/tools/pack/out/bootfs/sprite 0 disk : c CopyRootToFS(/home/zp/develop/a13_android4.1_v1.2/lichee/tools/pack/out/bootfs) ~~~ 检查可以发现是lichee/tools/pack/pack中的打包脚本的这句出错: `fsbuild bootfs.ini split_xxxx.fex` 这个fsbuild在运行时貌似无法打包bootfs的二级目录,不知为何。。有些人却没有反馈有这个问题,应该是个人的环境不同。 由于fsbuild是二进制提供的,只能通过其作用揣测实际功能,经过试验,上面那句可以用以下脚本代替, 基本作用就是构造一个fat文件系统镜像。 ~~~ dd if=/dev/zero of=bootfs.fex bs=1M count=12 mkfs.vfat bootfs.fex sudo mount bootfs.fex /mnt sudo cp -r bootfs/* /mnt sync sudo umount /mnt cat split_xxxx.fex >> bootfs.fex ~~~ 3. 分区大小的问题(虽然不导致编译失败,但是启动时会造成错误) 如果往system.img里加入了太多东西,可能导致超出了默认的分区大小(512M),则需要修改默认分区规划 验证system.img的实际大小: `simg2img system.img system.bin` 如果生成的system.bin大小刚好是512M,并且可以挂载,那就是正常的。 如果大小超过了512M,或者挂载时出错,那么就需要修正分区配置。 配置文件在lichee/tools/pack/chips/sun5i/configs/android/a13-evb/sys_config.fex 修改大小即可。 ~~~ ;------------------------------>nandd, android real rootfs [partition3] class_name = DISK name = system size_hi = 0 size_lo = 524288 user_type = 1 ro = 0 ~~~ ##4. 镜像下载 前面pack打包完成后,会生成sun5i_android_a13-evb.img,这就是刷机镜像 镜像烧录工具是网盘中的PhoenixCard,打开后选择tf卡对应盘符,以及待烧录镜像,选择**卡启动**,进行烧录 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/77805d12cdca7a2c82220dc65501c9dc_762x500.png) ### 常见烧录错误 1.偶尔会出现'处理出错'的提示,这时候一般只要重新烧录即可 ##5. 启动系统的适配过程 通过以上步骤编译的img还是不能在荔枝派上启动的,前面只能算是编译过一遍evb的安卓,需要在荔枝派上启动,还得进行一系列适配工作。 ### 第一次启动(boot1跳转失败) 系统默认串口为UART1,接串口查看信息: ~~~ dram size =512 0xffffffff,0xffffffff super_standby_flag = 0 HELLO! BOOT0 is starting! boot0 version : 1.5.2 The size of Boot1 is 0x00036000. Fail in checking boot1. Ready to disable icache. Fail in loading Boot1. Jump to Fel. ~~~ 可见DDR已被识别,但是加载boot1失败。 这其中的原因是DDR虽然被识别,但是参数配置错误,导致运行出错,所以我们需要先配置正确的DDR参数。 DDR参数记录在sys_config1.fex中,这里不过多解释sys_config1.fex的字段,直接使用之前在debian中适配好的fex文件覆盖 lichee/tools/pack/chips/sun5i/configs/android/a13-evb/sys_config1.fex 然后重新进行安卓编译过程。 编译完成后,可以直接重新烧写完整镜像,也可以只更新uboot和bootfs,后者需要对编译系统比较了解,在此不详细展开。 重新烧录后,可以看到闪过了两个开机画面,说明已经可以启动到linux内核了。 ### 第二次启动(启动介质错误) 按前面修改后,启动会卡在第二张开机画面,查看串口信息: ~~~ [ 16.009615] init: buffer : /dev/block/nande [ 16.014564] init: do_umount: /data [ 16.018071] init: do_umount error = Invalid argument [ 17.390045] usb 2-1: device not accepting address 2, error -110 [ 17.450200] ehci_irq: port change detect [ 17.454145] ehci_irq: port change detect [ 21.007468] init: buffer : /dev/block/nandh [ 21.012161] init: do_umount: /cache [ 21.015755] init: do_umount error = Invalid argument [ 21.022007] init: open device error :No such file or directory [ 31.008863] init: buffer : /dev/block/nandi [ 31.013556] init: do_umount: /databk [ 31.017237] init: do_umount error = Invalid argument [ 31.029268] init: cannot find '/system/bin/sh', disabling 'console' [ 31.035766] init: cannot find '/system/bin/servicemanager', disabling 'servicemanager' [ 31.043742] init: cannot find '/system/bin/vold', disabling 'vold' [ 31.049968] init: cannot find '/system/bin/netd', disabling 'netd' [ 31.056192] init: cannot find '/system/bin/debuggerd', disabling 'debuggerd' [ 31.063282] init: cannot find '/system/bin/rild', disabling 'ril-daemon' [ 31.069987] init: cannot find '/system/bin/surfaceflinger', disabling 'surfaceflinger' [ 31.077943] init: cannot find '/system/bin/app_process', disabling 'zygote' [ 31.084939] init: cannot find '/system/bin/drmserver', disabling 'drm' [ 31.091502] init: cannot find '/system/bin/mediaserver', disabling 'media' [ 31.098387] init: cannot find '/system/bin/dbus-daemon', disabling 'dbus' [ 31.105211] init: cannot find '/system/bin/installd', disabling 'installd' [ 31.112125] init: cannot find '/system/etc/install-recovery.sh', disabling 'flash_recovery' [ 31.120541] init: cannot find '/system/bin/keystore', disabling 'keystore' [ 31.127432] init: cannot find '/system/bin/u3gmonitor', disabling 'u3gmonitor' [ 31.135780] init: cannot find '/system/bin/sh', disabling 'console' ~~~ 可见是tf卡启动与nand启动的不同造成linux内核挂载根文件系统出错,所以需要修改开机启动脚本,即 \*.rc文件 device/softwinner/nuclear-evb/init.sun5i.rc device/softwinner/nuclear-evb/ueventd.sun5i.rc 将其中的nandX按下面对应关系修改 ~~~ nanda —— mmcblk0p2 nandb —— mmcblk0p5 nandc —— mmcblk0p6 nandd —— mmcblk0p7 nande —— mmcblk0p8 nandf —— mmcblk0p9 nandg —— mmcblk0p10 nandh —— mmcblk0p11 nandi —— mmcblk0p12 ~~~ 其中有一句挂载剩余空间的替换也对应替换: ~~~ #format_userdata /dev/block/nandj NUCLEAR exec /system/bin/busybox mount -t vfat /dev/block/mmcblk0p1 /mnt/sdcard ~~~ 再修改vold.fstab,开机挂载方式,前面两行改成以下,即sd卡0作为sdcard,sd卡2作为外置sd卡 ~~~ dev_mount sdcard /mnt/sdcard auto /devices/platform/sunxi-mmc.0/mmc_host dev_mount extsd /mnt/extsd auto /devices/platform/sunxi-mmc.2/mmc_host ~~~ > 如果需要修改成sd卡2启动,则还需要修改uboot代码 > lichee\u-boot\include\configs中sun5i.a13.h文件中的卡启动定义 > `#define CONFIG_MMC_SUNXI_SLOT 2` 最后修改uboot的环境变量env.cfg (lichee/tools/pack/chips/sun5i/configs/android/default/env.cfg) 将mmc作为启动介质 ~~~ bootdelay=1 #default bootcmd, will change at runtime according to key press bootcmd=run setargs_mmc boot_normal#default nand boot #kernel command arguments console=ttyS0,115200 nand_root=/dev/system mmc_root=/dev/mmcblk0p7 init=/init loglevel=6 #set kernel cmdline if boot.img or recovery.img has no cmdline we will use this setargs_nand=setenv bootargs console=${console} root=${nand_root} init=${init} loglevel=${loglevel} partitions=${partitions} setargs_mmc=setenv bootargs console=${console} root=${mmc_root} init=${init} loglevel=${loglevel} partitions=${partitions} #nand command syntax: sunxi_flash read address partition_name read_bytes #0x40007800 = 0x40008000(kernel entry) - 0x800(boot.img header 2k) boot_normal=sunxi_flash read 40007800 boot;boota 40007800 boot_recovery=sunxi_flash read 40007800 recovery;boota 40007800 boot_fastboot=fastboot #recovery key recovery_key_value_max=0x13 recovery_key_value_min=0x10 #fastboot key fastboot_key_value_max=0x8 fastboot_key_value_min=0x2 ~~~ 修改完成后重新编译下安卓 为了省事,可以不下载整个镜像,只更新boot.fex和env.fex(lichee/tools/pack/out下) 在linux下,使用fdisk -l查看tf卡分区: ~~~ Device Boot Start End Blocks Id System /dev/sdb1 3448832 15595518 6073343+ b W95 FAT32 //剩余空间作为u盘 /dev/sdb2 * 73728 106495 16384 6 FAT16 //bootfs,含uboot /dev/sdb3 1 3448832 1724416 85 Linux extended /dev/sdb5 106496 139263 16384 83 Linux //env.fex /dev/sdb6 139264 204799 32768 83 Linux //boot.fex,含linux内核及ramdisk /dev/sdb7 204800 1253375 524288 83 Linux //system分区 /dev/sdb8 1253376 2301951 524288 83 Linux //data分区 /dev/sdb9 2301952 2334719 16384 83 Linux //misc分区 /dev/sdb10 2334720 2400255 32768 83 Linux //recovery分区 /dev/sdb11 2400256 2924543 262144 83 Linux //cache分区 /dev/sdb12 2924544 3448831 262144 83 Linux //databk分区 ~~~ 所以只需更新两个分区: ~~~ root@ubuntu64:/home/zp# dd if=env.fex of=/dev/sdb5 256+0 records in 256+0 records out 131072 bytes (131 kB) copied, 0.097856 s, 1.3 MB/s root@ubuntu64:/home/zp# dd if=boot.fex of=/dev/sdb6 19916+0 records in 19916+0 records out 10196992 bytes (10 MB) copied, 8.54376 s, 1.2 MB/s root@ubuntu64:/home/zp# sync ~~~ 更新之后即可成功进入到安卓系统~ ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/488a185c2d50f3f7447efb621d4d836e_2976x3968.jpg) 虽然此时可以进入系统,但是很多外设不能运行,这些外设的驱动适配见后面的外设适配解析。
';

安卓系统适配全解析

最后更新于:2022-04-01 23:26:57

';

ubuntu

最后更新于:2022-04-01 23:26:55

';

debian

最后更新于:2022-04-01 23:26:53

';