当前位置: 首页 > news >正文

最先进的深圳网站建设/离我最近的电脑培训中心

最先进的深圳网站建设,离我最近的电脑培训中心,天津装修公司做网站,百度收录较好的网站目录 一、顶层Make分析 二、添加一个新的单板 2.1 Kconfig 2.2 Makefile 2.2.1 顶层Makefile 2.2.2 platform下的Makefile 2.2.3 platform下的bsp.mk文件 2.3 编译与调试 2.4 解决链接错误 三、内核启动流程的学习 3.1 韦东山老师总结的启动四步 3.2 启动文件分析…

目录

一、顶层Make分析

二、添加一个新的单板

2.1 Kconfig

2.2 Makefile

2.2.1 顶层Makefile 

2.2.2 platform下的Makefile

2.2.3 platform下的bsp.mk文件

2.3 编译与调试

2.4 解决链接错误

三、内核启动流程的学习

3.1 韦东山老师总结的启动四步

3.2 启动文件分析

3.3 main函数分析

3.4 OSmain函数分析

3.5 SystemInit函数分析


 

一、顶层Make分析

整体的编译框架和linux内核的一样都是分层的各自编译后由链接器来汇总

# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
#    conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
#    of conditions and the following disclaimer in the documentation and/or other materials
#    provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
#    to endorse or promote products derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.LITEOSTOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
export OS=$(shell uname -s)
ifneq ($(OS), Linux)
LITEOSTOPDIR := $(shell dirname $(subst \,/,$(LITEOSTOPDIR))/./)
endifLITEOSTHIRDPARTY := $(LITEOSTOPDIR)/../../third_partyexport LITEOSTOPDIR
export LITEOSTHIRDPARTY-include $(LITEOSTOPDIR)/tools/build/config.mkRM = -rm -rf
MAKE = make
__LIBS = libs
APPS = apps
ROOTFSDIR = rootfsdir
ROOTFS = rootfsLITEOS_TARGET = liteos
LITEOS_LIBS_TARGET = libs_target
LITEOS_MENUCONFIG_H = $(LITEOSTOPDIR)/include/generated/autoconf.h
LITEOS_PLATFORM_BASE = $(LITEOSTOPDIR)/platform
LITEOS_PLATFORM_MENUCONFIG_H = $(LITEOS_PLATFORM_BASE)/include/menuconfig.hifeq ($(LOSCFG_PLATFORM_HI3518EV300), y)
FSTYPE = jffs2
endif
ifeq ($(LOSCFG_PLATFORM_HI3516DV300), y)
FSTYPE = vfat
endif
ifeq ($(LOSCFG_PLATFORM_IMX6ULL), y)
FSTYPE = jffs2
endif
ifeq ($(LOSCFG_PLATFORM_STM32MP157), y)
FSTYPE = jffs2
ROOTFS_SIZE = 0xA00000
endif
ROOTFS_DIR = $(OUT)/rootfs
ROOTFS_ZIP = $(OUT)/rootfs.zip
VERSION =all: $(OUT) $(BUILD) $(LITEOS_TARGET) $(APPS)
lib: $(OUT) $(BUILD) $(LITEOS_LIBS_TARGET)help:$(HIDE)echo "-------------------------------------------------------"$(HIDE)echo "1.====make help:    get help infomation of make"$(HIDE)echo "2.====make:         make a debug version based the .config"$(HIDE)echo "3.====make debug:   make a debug version based the .config"$(HIDE)echo "4.====make release: make a release version for all platform"$(HIDE)echo "5.====make release PLATFORM=xxx:  make a release version only for platform xxx"$(HIDE)echo "6.====make rootfsdir: make a original rootfs dir"$(HIDE)echo "7.====make rootfs FSTYPE=***: make a original rootfs img"$(HIDE)echo "8.====make test: make the testsuits_app and put it into the rootfs dir"$(HIDE)echo "9.====make test_apps FSTYPE=***: make a rootfs img with the testsuits_app in it"$(HIDE)echo "xxx should be one of (hi3516cv300 hi3516ev200 hi3556av100/cortex-a53_aarch32 hi3559av100/cortex-a53_aarch64)"$(HIDE)echo "*** should be one of (jffs2)"$(HIDE)echo "-------------------------------------------------------"debug:$(HIDE)echo "=============== make a debug version  ==============="$(HIDE) $(MAKE) allrelease:
ifneq ($(PLATFORM),)$(HIDE)echo "=============== make a release version for platform $(PLATFORM) ==============="$(HIDE)$(SCRIPTS_PATH)/mklibversion.sh $(PLATFORM)
else$(HIDE)echo "================make a release version for all platform ==============="$(HIDE)$(SCRIPTS_PATH)/mklibversion.sh
endif##### make dynload #####
-include $(LITEOS_MK_PATH)/dynload.mk#-----need move when make version-----#
##### make lib #####
$(__LIBS): $(OUT) $(CXX_INCLUDE)ifeq ($(LOSCFG_PLATFORM_IMX6ULL),y)
BOARD_INCLUDE_DIR := $(LITEOSTOPDIR)/../../vendor/nxp/imx6ull/board
else ifeq ($(LOSCFG_PLATFORM_STM32MP157), y)
BOARD_INCLUDE_DIR := $(LITEOSTOPDIR)/../../vendor/st/stm32mp157/board
else
BOARD_INCLUDE_DIR := $(LITEOSTOPDIR)/../../vendor/hisi/hi35xx/$(LITEOS_PLATFORM)/config/board
endif$(OUT): $(LITEOS_MENUCONFIG_H)$(HIDE)mkdir -p $(OUT)/lib$(HIDE)$(CC) -I$(LITEOS_PLATFORM_BASE)/include -I$(BOARD_INCLUDE_DIR) \-E $(LITEOS_PLATFORM_BASE)/board.ld.S \-o $(LITEOS_PLATFORM_BASE)/board.ld -P$(BUILD):$(HIDE)mkdir -p $(BUILD)$(LITEOS_LIBS_TARGET): $(__LIBS)$(HIDE)for dir in $(LIB_SUBDIRS); \do $(MAKE) -C $$dir all || exit 1; \done$(HIDE)echo "=============== make lib done  ==============="##### make menuconfig #####
export CONFIG_=LOSCFG_
MENUCONFIG_PATH = $(LITEOSTOPDIR)/tools/menuconfig
KCONFIG_FILE_PATH = $(LITEOSTOPDIR)/Kconfigmenuconfig:$(MENUCONFIG_PATH)/mconf$< $(KCONFIG_FILE_PATH)genconfig:$(MENUCONFIG_PATH)/conf$(HIDE)mkdir -p include/config include/generated$< --silentoldconfig $(KCONFIG_FILE_PATH)-mv -f $(LITEOS_MENUCONFIG_H) $(LITEOS_PLATFORM_MENUCONFIG_H)
##### menuconfig end #######$(LITEOS_MENUCONFIG_H):
ifneq ($(LITEOS_PLATFORM_MENUCONFIG_H), $(wildcard $(LITEOS_PLATFORM_MENUCONFIG_H)))$(HIDE)$(MAKE) genconfig
endif
$(LITEOS_TARGET): $(__LIBS)$(HIDE)touch $(LOSCFG_ENTRY_SRC)$(HIDE)for dir in $(LITEOS_SUBDIRS); \do $(MAKE) -C $$dir all || exit 1; \done$(LD) $(LITEOS_LDFLAGS) $(LITEOS_TABLES_LDFLAGS) $(LITEOS_DYNLDFLAGS) -Map=$(OUT)/$@.map -o $(OUT)/$@ --start-group $(LITEOS_LIBDEP) --end-group
#       $(SIZE) -t --common $(OUT)/lib/*.a >$(OUT)/$@.objsize$(OBJCOPY) -O binary $(OUT)/$@ $(LITEOS_TARGET_DIR)/$@.bin
ifeq ($(LOSCFG_PLATFORM_STM32MP157), y)mkimage.stm32 -T stm32image -a 0xC0100000 -e 0xC0100000 -d $(LITEOS_TARGET_DIR)/$@.bin $(LITEOS_TARGET_DIR)/liteos.stm32mkimage.stm32 -A arm -O linux -T kernel -C none -a 0xC0100000 -e 0xC0100000 -n liteos-a -d $(LITEOS_TARGET_DIR)/$@.bin $(LITEOS_TARGET_DIR)/liteos_with_uboot_header.bin
endif$(OBJDUMP) -t $(OUT)/$@ |sort >$(OUT)/$@.sym.sorted$(OBJDUMP) -d $(OUT)/$@ >$(OUT)/$@.asm
#       $(NM) -S --size-sort $(OUT)/$@ >$(OUT)/$@.size$(APPS): $(LITEOS_TARGET)$(HIDE)$(MAKE) -C apps allprepare:$(HIDE)mkdir -p $(OUT)/musl
ifeq ($(LOSCFG_COMPILER_CLANG_LLVM), y)$(HIDE)cp -f $(LITEOSTOPDIR)/../../prebuilts/lite/sysroot/usr/lib/$(LLVM_TARGET)/a7_softfp_neon-vfpv4/libc.so $(OUT)/musl$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/lib/$(LLVM_TARGET)/c++/a7_softfp_neon-vfpv4/libc++.so $(OUT)/musl
else$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/target/usr/lib/libc.so $(OUT)/musl$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/arm-linux-musleabi/lib/libstdc++.so.6 $(OUT)/musl$(HIDE)cp -f $(LITEOS_COMPILER_PATH)/arm-linux-musleabi/lib/libgcc_s.so.1 $(OUT)/musl$(STRIP) $(OUT)/musl/*
endif$(ROOTFSDIR): prepare $(APPS)$(HIDE)$(MAKE) clean -C apps$(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/rootfsdir.sh $(OUT)/bin $(OUT)/musl $(ROOTFS_DIR))
ifneq ($(VERSION),)$(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/releaseinfo.sh "$(VERSION)" $(ROOTFS_DIR))
endif$(ROOTFS): $(ROOTFSDIR)$(HIDE)$(shell $(LITEOSTOPDIR)/tools/scripts/make_rootfs/rootfsimg.sh $(ROOTFS_DIR) $(FSTYPE)  ${ROOTFS_SIZE})$(HIDE)cd $(ROOTFS_DIR)/.. && zip -r $(ROOTFS_ZIP) $(ROOTFS)
ifneq ($(OUT), $(LITEOS_TARGET_DIR))$(HIDE)mv $(ROOTFS_DIR) $(LITEOS_TARGET_DIR)rootfs
endifclean:$(HIDE)for dir in $(LITEOS_SUBDIRS); \do $(MAKE) -C $$dir clean|| exit 1; \done$(HIDE)$(MAKE) -C apps clean$(HIDE)$(RM) $(__OBJS) $(LITEOS_TARGET) $(OUT) $(BUILD) $(LITEOS_MENUCONFIG_H) *.bak *~$(HIDE)$(RM) $(LITEOS_PLATFORM_MENUCONFIG_H)$(HIDE)$(RM) include$(HIDE)$(MAKE) cleanrootfs$(HIDE)echo "clean $(LITEOS_PLATFORM) finish"cleanall:$(HIDE)$(RM) $(LITEOSTOPDIR)/out$(HIDE)find $(LITEOS_PLATFORM_BASE)/ -name board.ld -exec rm -rf {} \;$(HIDE)cd sample/sample_osdrv;make clean;cd ../..;$(HIDE)echo "clean all"cleanrootfs:$(HIDE)$(RM) $(OUT)/rootfs$(HIDE)$(RM) $(OUT)/rootfs.zip$(HIDE)$(RM) $(OUT)/rootfs.img.PHONY: all lib clean cleanall $(LITEOS_TARGET) debug release help

下面是apps目录的make


include ../.config
include ./module.mkHIDE := @
APPS := appall: $(APPS)# Make
$(APPS):
ifneq ($(APP_SUBDIRS), )$(HIDE) for dir in $(APP_SUBDIRS); do $(MAKE) -C $$dir ; done
endifclean:
ifneq ($(APP_SUBDIRS), )$(HIDE) for dir in $(APP_SUBDIRS); do $(MAKE) -C $$dir clean; done
endif.PHONY: all $(APPS) clean

其它的也类似每一层make都有两个配套的mk文件来描述资源

如果这个APP_SUBDIRS不是空的就会遍历每个目录去make

        最底层的make和源码放一起的这些就会去真正的进行编译操作。里面放了对应的编译规则

好处就是整个软件的最终结果被按功能分别编译,我们可以针对性的开启对应功能的编译,都编译后统一链接。 

        其实随着不断学习,感觉理解起来变得越来越容易了,以前觉得大型工程中的makefile是座山,现在充其量就是个小土包。有这种感觉的前提是我自己从0到1做了一次编译框架。然后现在再来看就有这种感觉了。

二、添加一个新的单板

        这个地方要感谢韦东山老师了,因为鸿蒙只适配海思的芯片,别人想移植就得知道全部源码才行。但是为了不泄露机密,核心的代码是不开源的。我们没法直接移植。韦老师接触过这部分做个一个补丁文件可以根据这个文件不断拓展新单板。按老师的话说留下了一个火种。

        既然这样我想试试能不能移植到我的另一块单板exynos4412上。不一定会成功如果耗时过多的话我就放到毕业后再去做。下面记录一下移植过程。

2.1 Kconfig

vi platform/Kconfig

        仿照韦东山老师添加的两个我也添加了一个exynos4412.

        现在其实有个问题,大家看图应该可以看出来,其它是四个都是ARM Cotex-A7的我加的这个是A9的。在鸿蒙的官网上没说是不是支持A9,(不排除我没找到的情况)。在老师的技术交流群里也没有人能回答我,咱们就当他支持先试试好啦。

现在就有这个咯

为什么缺了一块内容

        因为当前Kconfig里只有A7的配置。没办法了或许能改但是要改的地方还是有点多的暂时先不弄了。

再来看看makefile

2.2 Makefile

2.2.1 顶层Makefile 

指定文件系统的类型和大小

然后指定我们取board资源的目录

这里也有修改,但是不清楚改了啥,后面看下源码对比一手

        然后是这里看样子是对bin文件的一些处理这里只有stm32mp157的,老师说我们的可以放到后面做接着往下看。

这里也有改动,看样子是跟文件系统的修改

顶层的makefile就改完了

2.2.2 platform下的Makefile

        这里是一个匹配规则如果这里的某个芯片i型号被选择了就把对应的源码加到编译的对象里

我们来添加一下。

2.2.3 platform下的bsp.mk文件

  1. HWI_TYPE := arm/interrupt/gic

    • HWI_TYPE 可能是指硬件中断(HWI)的类型或使用的硬件中断控制器(GIC)。arm/interrupt/gic 表示使用ARM架构下的GIC(Generic Interrupt Controller)作为中断控制器。
  2. TIMER_TYPE := hisoc/timer

    • TIMER_TYPE 表示定时器的类型或所使用的硬件定时器。hisoc/timer 可能是特定于某种SoC(System on a Chip)的定时器实现。
  3. HRTIMER_TYPE := hisoc/hrtimer

    • HRTIMER_TYPE 可能是高精度定时器的类型或实现。hisoc/hrtimer 可能是特定于某种SoC的高精度定时器。
  4. NET_TYPE := hieth

    • NET_TYPE 表示网络类型的配置或使用的网络接口。hieth 可能是某种特定的网络硬件或驱动。
  5. UART_TYPE := amba_pl011

    • UART_TYPE 表示UART(通用异步收发传输器)的类型或使用的硬件。amba_pl011 是ARM公司的一个UART控制器。
  6. USB_TYPE := usb3.0_hi3518ev300

    • USB_TYPE 表示USB的类型或使用的USB控制器。usb3.0_hi3518ev300 可能是特定于HI3518EV300芯片的USB 3.0控制器。
  7. LITEOS_CMACRO_TEST += -DTEST3518EV300

    • 这一行在LITEOS_CMACRO_TEST变量中添加了一个编译宏定义-DTEST3518EV300。这通常用于在编译时定义特定的宏,可能用于条件编译或特定的测试目的。

        串口和USB并没有处理,不知道什么原因往下接着看。

        然后就是这里指定一下平台总线这一层的头文件路径。

2.3 编译与调试

make clean报错找不到脚本 

然后去对应文件找,发现和下面这个变量有关

向上找,发现没设置编译器的路径就会调用这个脚本来获取路径

设置不了

在Kconfig里查找发现没有添加我们的单板类型

现在就有了。使用默认的这个编译器

可以clean成功了

找不到board下的这个头文件

因为我们用的A9不是A7回去先改成A7试试

报错在输出目录找不到inculude的这个头文件

这里应该有很多东西可是我们没有

不对哦,想起来了,我把.config拿来了一份也不对,board我往上翻一下修改

破案了

完蛋还是这个错误

这个文件find不到

等等

../../

我悟了

经过我的一番复制

终于和韦东山老师的一样了。

改回A9报错巨多还是先按A7来吧

上面报错对应shell下的这几个目录

 

ok再次编译只剩链接错误了

2.4 解决链接错误

 找不到这个库

修改一下mk文件的名字

还有里面的名字

:1,$s/IMAX6ULL_BASE_DIR/EXYNOS4412_BASE_DIR

好再来编译一下

他说宏没定义

vi /home/book/program/openharmony/vendor/samsung/exynos4412/driver/mtd/spi_nor/src/common/spinor.c =150

又来一个宏没定义

我是基于6ull改的所以和韦东山老师的不太一样

又来个新的错误

这些其实都是对应mk文件和我们的新的文件路径名匹配错误导致的

解决掉了一个还有两个

drivers/hdf/lite/hdf_lite.mk

vendor/democom/hdf/hdf_vendor.mk

grep一下

还是这个mtd的问题

这里明明定义了但是说没被定义

说明还是makefile的问题,没引过去

这里我取巧一下直接看已修改的driver文件

补完报错没变证明不是因为这个

这个mtd到底是哪里呢

又查了另一个,这俩难兄难弟都在这个头文件里定义的

        回去看了遍视频发现我没把分区mount的操作这里注释掉,也就是说我不用和文件系统相关的操作就暂时不会出那两个错误


ld.lld: error: undefined symbol: GetDevSpinorOps
>>> referenced by ld-temp.o
>>>               lto.tmp:(SystemInit)

ld.lld: error: undefined symbol: GetMtdCharFops
>>> referenced by ld-temp.o
>>>               lto.tmp:(SystemInit)
Makefile:165: recipe for target 'liteos' failed
make: *** [liteos] Error 1
 

这俩是关联的。

暂时没错误了

三、内核启动流程的学习

这里我就完全照搬老师的思想了,后面我更全面的了解后在自己总结一个

3.1 韦东山老师总结的启动四步

内核启动流程可以分为4步骤(非官方):

  • 启动

    • 使用汇编代码编写,涉及非常底层的设置,比如CPU设置、代码重定位等等

    • 地址映射也在这里实现

    • 它最终会调用main函数

  • main函数

    • 以后的代码,基本都是使用C语言编写了

    • 主要工作是:调用OsMain进行各类初始化、最终会启动用户程序

  • OsMain函数

    • 进行操作系统层面的初始化,比如异常初始化、任务初始化、IPC初始化

    • 调用SystemInit

  • SystemInit

    • 偏向于应用程序的初始化

    • 挂载根文件系统

    • 启动第一个用户进程

        所有的软件运行都是和这个类似的其实,上电后就是只能跑一个程序从启动文件开始跳到C的主函数,在ARM的汇编里就是b main。我看过很多很多的代码包括裸机环境的,带RTOS的以及linux的。都是从汇编跳到最初的主函数,然后系统级别的程序来初始化后面的环境变量。裸机环境没有多任务的话就是while1死循环,有多任务的话就是搞个状态机的机制做任务跳转,因为只有一个核心永远都是单线程的。看似多人只不过是切换的快。可能10ns就换一次任务。

        而操作系统环境要做的就比较多了,多核理论上是可以真的多线程的。只是线程由大脑统一调度。光有脑子没有配套的硬件设备也不行啊。就得把内存给大家分一下。不然一人用一会不还是单线程么。有mpu(有的也叫mmu叫什么的都有反正就是管理内存的。cpu不能直接用物理地址,虚拟的地址都由它来分配)的话这时候他就该发挥作用了。偏了。回到我们的主题往下看。

3.2 启动文件分析

启动文件藏的比较深

最前面一定是初始化栈空间和向量表

/** Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:** 1. Redistributions of source code must retain the above copyright notice, this list of*    conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright notice, this list*    of conditions and the following disclaimer in the documentation and/or other materials*    provided with the distribution.** 3. Neither the name of the copyright holder nor the names of its contributors may be used*    to endorse or promote products derived from this software without specific prior written*    permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#define  ASSEMBLY
#include "arch_config.h"
#include "los_vm_boot.h"
#include "los_vm_zone.h"
#include "los_mmu_descriptor_v6.h"
#undef ASSEMBLY.global __exc_stack_top.global __irq_stack_top.global __fiq_stack_top.global __svc_stack_top.global __abt_stack_top.global __undef_stack_top.global __exc_stack.global __irq_stack.global __fiq_stack.global __svc_stack.global __abt_stack.global __undef_stack.extern __bss_start.extern __bss_end.extern hal_clock_initialize_start.extern los_bss_init.extern _osExceptFiqHdl.extern _osExceptAddrAbortHdl.extern _osExceptDataAbortHdl.extern _osExceptPrefetchAbortHdl.extern _osExceptSwiHdl.extern _osExceptUndefInstrHdl.extern __stack_chk_guard_setup.extern g_firstPageTable.extern g_mmuJumpPageTable.equ MPIDR_CPUID_MASK, 0xffU.fpu vfpv4.arm/* param0 is stack bottom, param1 is stack size, r11 hold cpu id */
.macro EXC_SP_SET param0, param1ldr    r1, =\param0mov    r0, \param1bl     sp_set
.endm/* param0 is stack top, param1 is stack size, param2 is magic num */
.macro STACK_MAGIC_SET param0, param1, param2ldr     r0, =\param0mov     r1, \param1ldr     r2, =\param2bl      excstack_magic
.endm/* param0 is physical address, param1 virtual address, param2 is sizes, param3 is flag */
.macro PAGE_TABLE_SET param0, param1, param2, param3ldr     r6, =\param0ldr     r7, =\param1ldr     r8, =\param2ldr     r10, =\param3bl      page_table_build
.endm.code   32.section ".vectors","ax"__exception_handlers:/**Assumption:  ROM code has these vectors at the hardware reset address.*A simple jump removes any address-space dependencies [i.e. safer]*/b   reset_vectorb   _osExceptUndefInstrHdlb   _osExceptSwiHdlb   _osExceptPrefetchAbortHdlb   _osExceptDataAbortHdlb   _osExceptAddrAbortHdlb   OsIrqHandlerb   _osExceptFiqHdl/* Startup code which will get the machine into supervisor mode */.global reset_vector.type   reset_vector,function
reset_vector:
#if defined(LOSCFG_PLATFORM_STM32MP157)ldr sp, =0xc0000000 + 0x1000000mov r0, #'S'bl uart_putc_phy
#endif
#if 1/** disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,* except if in HYP mode already*/mrs	r0, cpsrand	r1, r0, #0x1f		@ mask mode bitsteq	r1, #0x1a		@ test for HYP modebicne	r0, r0, #0x1f		@ clear all mode bitsorrne	r0, r0, #0x13		@ set SVC modeorr	r0, r0, #0xc0		@ disable FIQ and IRQmsr	cpsr,r0/** If I-cache is enabled invalidate it */mcr	p15, 0, r0, c7, c5, 0	@ invalidate icachemcr     p15, 0, r0, c7, c10, 4	@ DSBmcr     p15, 0, r0, c7, c5, 4	@ ISB/* do some early cpu setup: i/d cache disable, mmu disabled */
//    mrc     p15, 0, r0, c1, c0, 0
//    bic     r0, #(1<<12)
//    bic     r0, #(1<<2 | 1<<0)
//    mcr     p15, 0, r0, c1, c0, 0
#endif/* r11: delta of physical address and virtual address */adr     r11, pa_va_offsetldr     r0, [r11]sub     r11, r11, r0/* if we need to relocate to proper location or not */adr     r4, __exception_handlers            /* r4: base of load address */ldr     r5, =SYS_MEM_BASE                   /* r5: base of physical address */subs    r12, r4, r5                         /* r12: delta of load address and physical address */beq     reloc_img_to_bottom_done            /* if we load image at the bottom of physical address */
#if defined(LOSCFG_PLATFORM_STM32MP157)mov r0, #'R'bl uart_putc_phy
#endif/* we need to relocate image at the bottom of physical address */ldr     r7, =__exception_handlers           /* r7: base of linked address (or vm address) */ldr     r6, =__bss_start                    /* r6: end of linked address (or vm address) */sub     r6, r7                              /* r6: delta of linked address (or vm address) */add     r6, r4                              /* r6: end of load address */reloc_img_to_bottom_loop:ldr     r7, [r4], #4str     r7, [r5], #4cmp     r4, r6bne     reloc_img_to_bottom_loopsub     pc, r12nopsub     r11, r11, r12                       /* r11: eventual address offset */reloc_img_to_bottom_done:
#if defined(LOSCFG_PLATFORM_STM32MP157)mov r0, #'D'bl uart_putc_phy
#endifldr     r4, =g_firstPageTable               /* r4: physical address of translation table and clear it */add     r4, r4, r11bl      page_table_clearPAGE_TABLE_SET SYS_MEM_BASE, UNCACHED_VMM_BASE, UNCACHED_VMM_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED
#if defined(LOSCFG_PLATFORM_IMX6ULL) || defined(LOSCFG_PLATFORM_STM32MP157)PAGE_TABLE_SET DDR_RAMFS_ADDR, DDR_RAMFS_VBASE, DDR_RAMFS_SIZE, MMU_INITIAL_MAP_DEVICEPAGE_TABLE_SET LCD_FB_BASE, LCD_FB_VBASE, LCD_FB_SIZE, MMU_INITIAL_MAP_DEVICE
#endifPAGE_TABLE_SET SYS_MEM_BASE, KERNEL_VMM_BASE, KERNEL_VMM_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGSPAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_DEVICE_BASE, PERIPH_DEVICE_SIZE, MMU_INITIAL_MAP_DEVICEPAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_CACHED_BASE, PERIPH_CACHED_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGSPAGE_TABLE_SET PERIPH_PMM_BASE, PERIPH_UNCACHED_BASE, PERIPH_UNCACHED_SIZE, MMU_INITIAL_MAP_STRONGLY_ORDERED
#if defined(LOSCFG_PLATFORM_STM32MP157)PAGE_TABLE_SET GIC_PHY_BASE, GIC_VIRT_BASE, GIC_VIRT_SIZE, MMU_INITIAL_MAP_DEVICE
#endiforr     r8, r4, #MMU_TTBRx_FLAGS            /* r8 = r4 and set cacheable attributes on translation walk */ldr     r4, =g_mmuJumpPageTable             /* r4: jump pagetable vaddr */add     r4, r4, r11ldr     r4, [r4]add     r4, r4, r11                         /* r4: jump pagetable paddr */bl      page_table_clear/* build 1M section mapping, in order to jump va during turing on mmu:pa == pa, va == pa */mov     r6, pcmov     r7, r6                              /* r7: pa (MB aligned)*/lsr     r6, r6, #20                         /* r6: va l1 index */ldr     r10, =MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGSadd     r12, r10, r6, lsl #20               /* r12: pa |flags */str     r12, [r4, r7, lsr #(20 - 2)]        /* jumpTable[paIndex] = pt entry */rsb     r7, r11, r6, lsl #20                /* r7: va */str     r12, [r4, r7, lsr #(20 - 2)]        /* jumpTable[vaIndex] = pt entry */bl      mmu_setup                           /* set up the mmu */
#if defined(LOSCFG_PLATFORM_STM32MP157)mov r0, #'M'bl uart_putc_virt
#endif/* get cpuid and keep it in r11 */mrc     p15, 0, r11, c0, c0, 5and     r11, r11, #MPIDR_CPUID_MASKcmp     r11, #0bne     excstatck_loop_doneexcstatck_loop:/* clear out the interrupt and exception stack and set magic num to check the overflow */ldr     r0, =__undef_stackldr     r1, =__exc_stack_topbl      stack_initSTACK_MAGIC_SET __undef_stack, #OS_EXC_UNDEF_STACK_SIZE, OS_STACK_MAGIC_WORDSTACK_MAGIC_SET __abt_stack, #OS_EXC_ABT_STACK_SIZE, OS_STACK_MAGIC_WORDSTACK_MAGIC_SET __irq_stack, #OS_EXC_IRQ_STACK_SIZE, OS_STACK_MAGIC_WORDSTACK_MAGIC_SET __fiq_stack, #OS_EXC_FIQ_STACK_SIZE, OS_STACK_MAGIC_WORDSTACK_MAGIC_SET __svc_stack, #OS_EXC_SVC_STACK_SIZE, OS_STACK_MAGIC_WORDSTACK_MAGIC_SET __exc_stack, #OS_EXC_STACK_SIZE, OS_STACK_MAGIC_WORDexcstatck_loop_done:
warm_reset:/* initialize interrupt/exception environments */mov    r0, #(CPSR_IRQ_DISABLE |CPSR_FIQ_DISABLE|CPSR_IRQ_MODE)msr    cpsr, r0EXC_SP_SET __irq_stack_top, #OS_EXC_IRQ_STACK_SIZEmov    r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_UNDEF_MODE)msr    cpsr, r0EXC_SP_SET __undef_stack_top, #OS_EXC_UNDEF_STACK_SIZEmov    r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_ABT_MODE)msr    cpsr, r0EXC_SP_SET __abt_stack_top, #OS_EXC_ABT_STACK_SIZEmov    r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_FIQ_MODE)msr    cpsr, r0EXC_SP_SET __fiq_stack_top, #OS_EXC_FIQ_STACK_SIZE/* initialize CPSR (machine state register) */mov    r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE)msr    cpsr, r0/* Note: some functions in LIBGCC1 will cause a "restore from SPSR"!! */msr    spsr, r0/* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack */ldr    r0, =__svc_stack_topmov    r2, #OS_EXC_SVC_STACK_SIZEmul    r2, r2, r11sub    r0, r0, r2mov    sp, r0#ifndef  LOSCFG_PLATFORM_STM32MP157/* enable fpu+neon */MRC    p15, 0, r0, c1, c1, 2ORR    r0, r0, #0xC00BIC    r0, r0, #0xC000MCR    p15, 0, r0, c1, c1, 2LDR    r0, =(0xF << 20)MCR    p15, 0, r0, c1, c0, 2
#endif    MOV    r3, #0x40000000VMSR   FPEXC, r3LDR    r0, =__exception_handlersMCR    p15, 0, r0, c12, c0, 0cmp    r11, #0bne    cpu_startclear_bss:ldr    r1, =__bss_startldr    r2, =__bss_endmov    r0, #0bss_loop:cmp    r1, r2strlo  r0, [r1], #4blo    bss_loop#if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \defined(LOSCFG_CC_STACKPROTECTOR)bl     __stack_chk_guard_setup
#endif#ifdef LOSCFG_GDB_DEBUG/* GDB_START - generate a compiled_breadk,This function will get GDB stubs started, with a proper environment */bl     GDB_START.word  0xe7ffdeff
#endif
#if defined(LOSCFG_PLATFORM_STM32MP157)mov r0, 'm'bl uart_putc_virt
#endifbl     main_start_hang:b      _start_hangmmu_setup:mov     r12, #0mcr     p15, 0, r12, c8, c7, 0              /* Set c8 to control the TLB and set the mapping to invalid */isbmcr     p15, 0, r12, c2, c0, 2              /* Initialize the c2 register */isborr     r12, r4, #MMU_TTBRx_FLAGSmcr     p15, 0, r12, c2, c0, 0              /* Set attributes and set temp page table */isbmov     r12, #0x7                           /* 0b0111 */mcr     p15, 0, r12, c3, c0, 0              /* Set DACR with 0b0111, client and manager domian */isbmrc     p15, 0, r12, c1, c0, 0bic     r12, #(1 << 29 | 1 << 28)orr     r12, #(1 << 0)bic     r12, #(1 << 1)orr     r12, #(1 << 2)orr     r12, #(1 << 12)mcr     p15, 0, r12, c1, c0, 0              /* Set SCTLR with r12: Turn on the MMU, I/D cache Disable TRE/AFE */isbldr     pc,  =1f                            /* Convert to VA */
1:mcr     p15, 0, r8, c2, c0, 0               /* Go to the base address saved in C2: Jump to the page table */isbmov     r12, #0mcr     p15, 0, r12, c8, c7, 0isbsub     lr,  r11                            /* adjust lr with delta of physical address and virtual address */bx      lr.code  32.global reset_platform.type   reset_platform,function
reset_platform:
#ifdef A7SEM_HAL_ROM_MONITOR/* initialize CPSR (machine state register) */mov    r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE)msr    cpsr, r0b      warm_reset
#elsemov    r0, #0mov    pc, r0   // Jump to reset vector
#endif
cpu_start:bl     secondary_cpu_startb      ./** set sp for current cpu* r1 is stack bottom, r0 is stack size, r11 hold cpu id*/
sp_set:mul    r3, r0, r11sub    r2, r1, r3mov    sp, r2bx     lr          /* set sp *//** r4: page table base address* r5 and r6 will be used as variable*/
page_table_clear:mov     r5, #0mov     r6, #0
0:str     r5, [r4, r6, lsl #2]add     r6, #1cmp     r6, #0x1000                         /* r6 < 4096 */blt     0bbx      lr/** r4: page table base address* r6: physical address* r7: virtual address* r8: sizes* r10: flags* r9 and r12 will be used as variable*/
page_table_build:mov     r9, r6bfc     r9, #20, #12                        /* r9: pa % MB */add     r8, r8, r9add     r8, r8, #(1 << 20)sub     r8, r8, #1lsr     r6, #20                             /* r6 = physical address / MB */lsr     r7, #20                             /* r7 = virtual address / MB */lsr     r8, #20                             /* r8 = roundup(size, MB) */page_table_build_loop:orr     r12, r10, r6, lsl #20               /* r12: flags | physAddr */str     r12, [r4, r7, lsl #2]               /* gPgTable[l1Index] = physAddr | flags */add     r6, #1                              /* physAddr+ */add     r7, #1                              /* l1Index++ */subs    r8, #1                              /* sizes-- */bne     page_table_build_loopbx      lr/** init stack to initial value* r0 is stack mem start, r1 is stack mem end*/
stack_init:ldr     r2, =OS_STACK_INITldr     r3, =OS_STACK_INIT/* Main loop sets 32 bytes at a time. */
stack_init_loop:.irp    offset, #0, #8, #16, #24strd    r2, r3, [r0, \offset].endradd     r0, #32cmp     r0, r1blt     stack_init_loopbx      lrpa_va_offset:.word   ./** set magic num to stack top for all cpu* r0 is stack top, r1 is stack size, r2 is magic num*/
excstack_magic:mov     r3, #0
excstack_magic_loop:str     r2, [r0]add     r0, r0, r1add     r3, r3, #1cmp     r3, #CORE_NUMblt     excstack_magic_loopbx      lr/** 0xe51ff004 = "ldr  pc, [pc, #-4]"* next addr value will be the real booting addr*/
_bootaddr_setup:mov     r0, #0ldr     r1, =0xe51ff004str     r1, [r0]add     r0, r0, #4ldr     r1, =SYS_MEM_BASEstr     r1, [r0]dsbisbbx      lrinit_done:.long  0xDEADB00B.code  32.datainit_flag:.balign 4.long   0/** Temporary interrupt stack*/.section ".int_stack", "wa", %nobits.align  3__undef_stack:.space OS_EXC_UNDEF_STACK_SIZE * CORE_NUM
__undef_stack_top:__abt_stack:.space OS_EXC_ABT_STACK_SIZE * CORE_NUM
__abt_stack_top:__irq_stack:.space OS_EXC_IRQ_STACK_SIZE * CORE_NUM
__irq_stack_top:__fiq_stack:.space OS_EXC_FIQ_STACK_SIZE * CORE_NUM
__fiq_stack_top:__svc_stack:.space OS_EXC_SVC_STACK_SIZE * CORE_NUM
__svc_stack_top:__exc_stack:.space OS_EXC_STACK_SIZE * CORE_NUM
__exc_stack_top:

        具体内容自行阅读

        这里有两个启动代码内容看起来也有点像,不太清楚区别,可以一个是单核启动一个是多核启动。

        之前研究exynos4412的时候发现cpu0内就有控制其它三个核心的寄存器。所以启动时是cpu0先启动再去选择是不是引导其它内核启动。不清楚别的处理器是不是也是这样设计的。

        下面是对上面代码的简单解析。

3.3 main函数分析

/** Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:** 1. Redistributions of source code must retain the above copyright notice, this list of*    conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright notice, this list*    of conditions and the following disclaimer in the documentation and/or other materials*    provided with the distribution.** 3. Neither the name of the copyright holder nor the names of its contributors may be used*    to endorse or promote products derived from this software without specific prior written*    permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include "los_config.h"
#include "los_task_pri.h"
#include "los_swtmr_pri.h"
#include "los_printf.h"
#include "los_atomic.h"
#include "gic_common.h"
#include "uart.h"
#include "los_process_pri.h"
#include "los_arch_mmu.h"#if (LOSCFG_KERNEL_SMP == YES)
STATIC Atomic g_ncpu = 1;
#endifLITE_OS_SEC_TEXT_INIT VOID OsSystemInfo(VOID)
{
#ifdef LOSCFG_DEBUG_VERSIONconst CHAR *buildType = "debug";
#elseconst CHAR *buildType = "release";
#endif /* LOSCFG_DEBUG_VERSION */PRINT_RELEASE("\n******************Welcome******************\n\n""Processor   : %s"
#if (LOSCFG_KERNEL_SMP == YES)" * %d\n""Run Mode    : SMP\n"
#else"\n""Run Mode    : UP\n"
#endif"GIC Rev     : %s\n""build time  : %s %s\n""Kernel      : %s %d.%d.%d.%d/%s\n""\n*******************************************\n",LOS_CpuInfo(),
#if (LOSCFG_KERNEL_SMP == YES)LOSCFG_KERNEL_SMP_CORE_NUM,
#endifHalIrqVersion(), __DATE__, __TIME__,\KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, buildType);
}LITE_OS_SEC_TEXT_INIT VOID secondary_cpu_start(VOID)
{
#if (LOSCFG_KERNEL_SMP == YES)UINT32 cpuid = ArchCurrCpuid();OsArchMmuInitPerCPU();OsCurrTaskSet(OsGetMainTask());/* increase cpu counter */LOS_AtomicInc(&g_ncpu);/* store each core's hwid */CPU_MAP_SET(cpuid, OsHwIDGet());HalIrqInitPercpu();OsCurrProcessSet(OS_PCB_FROM_PID(OsGetKernelInitProcessID()));OsSwtmrInit();OsIdleTaskCreate();OsStart();while (1) {__asm volatile("wfi");}
#endif
}#if (LOSCFG_KERNEL_SMP == YES)
#ifdef LOSCFG_TEE_ENABLE
#define TSP_CPU_ON  0xb2000011UL
STATIC INT32 raw_smc_send(UINT32 cmd)
{register UINT32 smc_id asm("r0") = cmd;do {asm volatile ("mov r0, %[a0]\n""smc #0\n": [a0] "+r"(smc_id));} while (0);return (INT32)smc_id;
}STATIC VOID trigger_secondary_cpu(VOID)
{(VOID)raw_smc_send(TSP_CPU_ON);
}LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID)
{trigger_secondary_cpu();/* wait until all APs are ready */while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) {asm volatile("wfe");}
}
#else
#define CLEAR_RESET_REG_STATUS(regval) (regval) &= ~(1U << 2)
LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID)
{UINT32 regval;/* clear the slave cpu reset */READ_UINT32(regval, PERI_CRG30_BASE);CLEAR_RESET_REG_STATUS(regval);WRITE_UINT32(regval, PERI_CRG30_BASE);/* wait until all APs are ready */while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) {asm volatile("wfe");}
}
#endif /* LOSCFG_TEE_ENABLE */
#endif /* LOSCFG_KERNEL_SMP */LITE_OS_SEC_TEXT_INIT INT32 main(VOID)
{UINT32 uwRet = LOS_OK;OsSetMainTask();OsCurrTaskSet(OsGetMainTask());PRINT_RELEASE("\n******************Main******************\n\n");/* set smp system counter freq */
#if (LOSCFG_KERNEL_SMP == YES)
#ifndef LOSCFG_TEE_ENABLEHalClockFreqWrite(OS_SYS_CLOCK);
#endif
#endif/* system and chip info */OsSystemInfo();PRINT_RELEASE("\nmain core booting up...\n");uwRet = OsMain();if (uwRet != LOS_OK) {return LOS_NOK;}#if (LOSCFG_KERNEL_SMP == YES)PRINT_RELEASE("releasing %u secondary cores\n", LOSCFG_KERNEL_SMP_CORE_NUM - 1);release_secondary_cores();
#endifCPU_MAP_SET(0, OsHwIDGet());OsStart();while (1) {__asm volatile("wfi");}
}

3.4 OSmain函数分析

 

/** Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.** Redistribution and use in source and binary forms, with or without modification,* are permitted provided that the following conditions are met:** 1. Redistributions of source code must retain the above copyright notice, this list of*    conditions and the following disclaimer.** 2. Redistributions in binary form must reproduce the above copyright notice, this list*    of conditions and the following disclaimer in the documentation and/or other materials*    provided with the distribution.** 3. Neither the name of the copyright holder nor the names of its contributors may be used*    to endorse or promote products derived from this software without specific prior written*    permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include "los_config.h"
#include "string.h"
#include "stdio.h"
#include "los_oom.h"
#ifdef LOSCFG_COMPAT_LINUXKPI
#include "linux/workqueue.h"
#include "linux/module.h"
#endif
#include "los_sys.h"
#include "los_tick.h"
#include "los_task_pri.h"
#include "los_printf.h"
#include "los_swtmr.h"
#include "los_swtmr_pri.h"
#include "los_timeslice_pri.h"
#include "los_memory_pri.h"
#include "los_sem_pri.h"
#include "los_mux_pri.h"
#include "los_queue_pri.h"
#include "los_memstat_pri.h"
#include "los_hwi_pri.h"
#include "los_spinlock.h"
#include "los_mp.h"
#include "los_atomic.h"
#include "los_exc_pri.h"
#include "gic_common.h"
#include "los_vm_boot.h"#ifdef LOSCFG_FS_VFS
#include "fs/fs.h"
#include "fs/fs_operation.h"
#endif#if (LOSCFG_KERNEL_TRACE == YES)
#include "los_trace.h"
#endif#ifdef LOSCFG_KERNEL_CPUP
#include "los_cpup_pri.h"
#endif#ifdef LOSCFG_COMPAT_POSIX
#include "pprivate.h"
#endif#ifdef LOSCFG_DRIVERS_HDF_PLATFORM_UART
#include "console.h"
#endif
#ifdef LOSCFG_KERNEL_TICKLESS
#include "los_tickless.h"
#endif
#ifdef LOSCFG_ARCH_CORTEX_M7
#include "los_exc_pri.h"
#endif
#ifdef LOSCFG_MEM_RECORDINFO
#include "los_memrecord_pri.h"
#endif
#include "los_hw_tick_pri.h"
#include "los_hwi_pri.h"#if defined(LOSCFG_HW_RANDOM_ENABLE) || defined (LOSCFG_DRIVERS_RANDOM)
#include "randomdev.h"
#include "yarrow.h"
#endif
#ifdef LOSCFG_SHELL_DMESG
#include "dmesg_pri.h"
#endif
#ifdef LOSCFG_SHELL_LK
#include "shell_pri.h"
#endif#ifdef LOSCFG_KERNEL_PIPE
#include "pipe_common.h"
#endif#include "los_process_pri.h"
#include "los_futex_pri.h"#ifdef LOSCFG_KERNEL_VDSO
#include "los_vdso.h"
#endif#if (LOSCFG_KERNEL_LITEIPC == YES)
#include "hm_liteipc.h"
#endif#ifdef LOSCFG_DRIVERS_HIEVENT
#include "hievent_driver.h"
#endif#if (LOSCFG_BASE_CORE_HILOG == YES)
#include "los_hilog.h"
#endif#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */extern UINT32 OsSystemInit(VOID);
extern VOID SystemInit(VOID);LITE_OS_SEC_TEXT_INIT VOID osRegister(VOID)
{g_sysClock = OS_SYS_CLOCK;g_tickPerSecond =  LOSCFG_BASE_CORE_TICK_PER_SECOND;return;
}LITE_OS_SEC_TEXT_INIT VOID OsStart(VOID)
{LosProcessCB *runProcess = NULL;LosTaskCB *taskCB = NULL;UINT32 cpuid = ArchCurrCpuid();OsTickStart();LOS_SpinLock(&g_taskSpin);taskCB = OsGetTopTask();runProcess = OS_PCB_FROM_PID(taskCB->processID);runProcess->processStatus |= OS_PROCESS_STATUS_RUNNING;
#if (LOSCFG_KERNEL_SMP == YES)/** attention: current cpu needs to be set, in case first task deletion* may fail because this flag mismatch with the real current cpu.*/taskCB->currCpu = cpuid;runProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(runProcess->processStatus);
#endifOS_SCHEDULER_SET(cpuid);PRINTK("cpu %d entering scheduler\n", cpuid);OsStartToRun(taskCB);
}LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsIpcInit(VOID)
{UINT32 ret;
#if (LOSCFG_BASE_IPC_SEM == YES)ret = OsSemInit();if (ret != LOS_OK) {return ret;}
#endif#if (LOSCFG_BASE_IPC_QUEUE == YES)ret = OsQueueInit();if (ret != LOS_OK) {return ret;}
#endifreturn LOS_OK;
}#ifdef LOSCFG_KERNEL_PIPE
LITE_OS_SEC_TEXT_INIT STATIC VOID OsDriverPipeInit(VOID)
{(VOID)pipe_init();
}
#endif#ifdef LOSCFG_DRIVERS_HIEVENT
LITE_OS_SEC_TEXT_INIT STATIC VOID OsDriverHiEventInit(VOID)
{(VOID)HieventInit();
}
#endif#ifdef LOSCFG_COMPAT_BSD
extern void configure (void);
LITE_OS_SEC_TEXT_INIT STATIC INT32 OsBsdInit(VOID)
{configure();mi_startup(SI_SUB_ARCH_INIT);return LOS_OK;
}
#endifLITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID)
{UINT32 ret;osRegister();#ifdef LOSCFG_SHELL_DMESGret = OsDmesgInit();if (ret != LOS_OK) {return ret;}
#endif#ifdef LOSCFG_SHELL_LKOsLkLoggerInit(NULL);
#endif#ifdef LOSCFG_EXC_INTERACTION
#ifdef LOSCFG_ARCH_CORTEX_M7/* 4096: 4K space for Stack */ret = OsMemExcInteractionInit((UINT32)&__bss_end + 4096);
#elseret = OsMemExcInteractionInit((UINTPTR)&__bss_end);
#endifif (ret != LOS_OK) {return ret;}
#endif#if (LOSCFG_PLATFORM_HWI == YES)OsHwiInit();
#endifOsExcInit();ret = OsTickInit(g_sysClock, LOSCFG_BASE_CORE_TICK_PER_SECOND);if (ret != LOS_OK) {return ret;}#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS
#ifdef LOSCFG_DRIVERSextern void uart_init(void);uart_init();
#endif
#ifdef LOSCFG_SHELL
#endif //LOSCFG_SHELL
#endif //LOSCFG_PLATFORM_UART_WITHOUT_VFSret = OsTaskInit();if (ret != LOS_OK) {PRINT_ERR("OsTaskInit error\n");return ret;}#if ((LOSCFG_BASE_IPC_QUEUE == YES) || (LOSCFG_BASE_IPC_MUX == YES) || (LOSCFG_BASE_IPC_SEM == YES))ret = OsIpcInit();if (ret != LOS_OK) {return ret;}
#endifret = OsSysMemInit();if (ret != LOS_OK) {PRINT_ERR("OsSysMemInit error\n");return ret;}SyscallHandleInit();/** CPUP should be inited before first task creation which depends on the semaphore* when LOSCFG_KERNEL_SMP_TASK_SYNC is enabled. So don't change this init sequence* if not neccessary. The sequence should be like this:* 1. OsIpcInit* 2. OsCpupInit* 3. other inits have task creation*/
#ifdef LOSCFG_KERNEL_CPUPret = OsCpupInit();if (ret != LOS_OK) {PRINT_ERR("OsCpupInit error\n");return ret;}
#endifret = OsKernelInitProcess();if (ret != LOS_OK) {return ret;}#if (LOSCFG_BASE_CORE_SWTMR == YES)ret = OsSwtmrInit();if (ret != LOS_OK) {return ret;}
#endif#ifdef LOSCFG_KERNEL_CPUPOsCpupGuardCreator();
#endif#if (LOSCFG_KERNEL_SMP == YES)(VOID)OsMpInit();
#endif#if defined(LOSCFG_HW_RANDOM_ENABLE) || defined (LOSCFG_DRIVERS_RANDOM)random_alg_context.ra_init_alg(NULL);run_harvester_iterate(NULL);
#endif#ifdef LOSCFG_COMPAT_BSDret = OsBsdInit();if (ret != LOS_OK) {PRINT_ERR("init bsd failed!\n");return ret;}
#endif#ifdef LOSCFG_KERNEL_PIPEOsDriverPipeInit();
#endifret = OsSystemInit();if (ret != LOS_OK) {return ret;}#if LOSCFG_DRIVERS_HIEVENTOsDriverHiEventInit();
#endif#if (LOSCFG_KERNEL_TRACE == YES)LOS_TraceInit();
#endif#if (LOSCFG_KERNEL_LITEIPC == YES)ret = LiteIpcInit();if (ret != LOS_OK) {return ret;}
#endif#if (LOSCFG_BASE_CORE_HILOG == YES)ret = HiLogDriverInit();if (ret != LOS_OK) {return ret;}
#endif#ifdef LOSCFG_KERNEL_VDSOret = OsInitVdso();if (ret != LOS_OK) {return ret;}
#endifret = OsFutexInit();if (ret != LOS_OK) {PRINT_ERR("Create futex failed : %d!\n", ret);return ret;}ret = OomTaskInit();if (ret != LOS_OK) {return ret;}return LOS_OK;
}STATIC UINT32 OsSystemInitTaskCreate(VOID)
{UINT32 taskID;TSK_INIT_PARAM_S sysTask;(VOID)memset_s(&sysTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));sysTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SystemInit;sysTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;sysTask.pcName = "SystemInit";sysTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;sysTask.uwResved = LOS_TASK_STATUS_DETACHED;
#if (LOSCFG_KERNEL_SMP == YES)sysTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());
#endifreturn LOS_TaskCreate(&taskID, &sysTask);
}#ifdef LOSCFG_MEM_RECORDINFO
STATIC UINT32 OsMemShowTaskCreate(VOID)
{UINT32 taskID;TSK_INIT_PARAM_S appTask;(VOID)memset_s(&appTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));appTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsMemRecordShowTask;appTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;appTask.pcName = "memshow_Task";appTask.usTaskPrio = LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;appTask.uwResved = LOS_TASK_STATUS_DETACHED;return LOS_TaskCreate(&taskID, &appTask);
}
#endifUINT32 OsSystemInit(VOID)
{UINT32 ret;
#ifdef LOSCFG_FS_VFSlos_vfs_init();
#endif
#ifdef LOSCFG_COMPAT_LINUXKPIg_pstSystemWq = create_workqueue("system_wq");
#endifret = OsSystemInitTaskCreate();if (ret != LOS_OK) {return ret;}
#ifdef LOSCFG_MEM_RECORDINFOret = OsMemShowTaskCreate();if (ret != LOS_OK) {PRINTK("create memshow_Task error %u\n", ret);return ret;}PRINTK("create memshow_Task ok\n");
#endif
#ifdef LOSCFG_KERNEL_TICKLESSLOS_TicklessEnable();
#endifreturn 0;
}#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */

3.5 SystemInit函数分析

这个函数做的比较重要

他在平台的board文件里,因为这些也和板子相关

#include "los_base.h"
#include "los_config.h"
#include "los_process_pri.h"
#include "lwip/init.h"
#include "lwip/tcpip.h"
#include "sys/mount.h"
#include "mtd_partition.h"
#include "console.h"UINT32 OsRandomStackGuard(VOID)
{return 0;
}static void imx6ull_mount_rootfs()
{
#if 0
#if 1	dprintf("register parition ...\n");if (add_mtd_partition("spinor", 0, 0x4000000, 0)){PRINT_ERR("add_mtd_partition fail\n");}dprintf("mount /dev/spinorblk0 / ...\n");//if (mount("/dev/spinorblk0", "/", "jffs2", MS_RDONLY, NULL))if (mount("/dev/spinorblk0", "/", "jffs2", 0, NULL)){PRINT_ERR("mount failed\n");}
#elsedprintf("mount /dev/ramdisk / ...\n");//if (mount("/dev/spinorblk0", "/", "jffs2", MS_RDONLY, NULL))if (mount("/dev/ramdisk", "/", "vfat", 0, NULL)){PRINT_ERR("mount failed\n");}
#endif
#endif
}static void imx6ull_driver_init()
{
#if 0	extern int my_ramdisk_init(void);if (my_ramdisk_init()){PRINT_ERR("my_ramdisk_init failed\n");}#else	extern int spinor_init(void);dprintf("spinor_init init ...\n");if (!spinor_init()){PRINT_ERR("spinor_init failed\n");}
#endif#ifdef LOSCFG_DRIVERS_VIDEOdprintf("imx6ull_fb_init init ...\n");extern int imx6ull_fb_init(void);if (imx6ull_fb_init()){PRINT_ERR("imx6ull_fb_init failed\n");}
#endif	}void SystemInit()
{
#ifdef LOSCFG_FS_PROCdprintf("proc fs init ...\n");extern void ProcFsInit(void);ProcFsInit();
#endif#ifdef LOSCFG_DRIVERS_MEMdprintf("mem dev init ...\n");extern int mem_dev_register(void);mem_dev_register();
#endifimx6ull_driver_init();imx6ull_mount_rootfs();#ifdef LOSCFG_DRIVERS_HDFextern int DeviceManagerStart(void);PRINT_RELEASE("DeviceManagerStart start ...\n");	if (DeviceManagerStart()) {PRINT_ERR("No drivers need load by hdf manager!");}dprintf("DeviceManagerStart end ...\n");
#endifextern int uart_dev_init(void);uart_dev_init();if (virtual_serial_init("/dev/uartdev-0") != 0){PRINT_ERR("virtual_serial_init failed");}if (system_console_init(SERIAL) != 0){PRINT_ERR("system_console_init failed\n");}if (OsUserInitProcess()){PRINT_ERR("Create user init process faialed!\n");}
}

相关文章:

003——移植鸿蒙

目录 一、顶层Make分析 二、添加一个新的单板 2.1 Kconfig 2.2 Makefile 2.2.1 顶层Makefile 2.2.2 platform下的Makefile 2.2.3 platform下的bsp.mk文件 2.3 编译与调试 2.4 解决链接错误 三、内核启动流程的学习 3.1 韦东山老师总结的启动四步 3.2 启动文件分析…...

罗马数字转整数-力扣通过自己编译器编译

学会将力扣题目用自己自带的编译软件编译---纯自己想的本题解法 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#xff0c; 罗马数字 2 写做 II &#xff0c;即为两…...

深入解析JVM加载机制

一、背景 Java代码被编译器变成生成Class字节码&#xff0c;但字节码仅是一个特殊的二进制文件&#xff0c;无法直接使用。因此&#xff0c;都需要放到JVM系统中执行&#xff0c;将Class字节码文件放入到JVM的过程&#xff0c;简称类加载。 二、整体流程 三、阶段逻辑分析 3…...

python redis中blpop和lpop的区别

python redis中lpop()方法是获取并删除左边第一个对象。 def lpop(self,name: str,count: Optional[int] None,) -> Union[Awaitable[Union[str, List, None]], Union[str, List, None]]:"""Removes and returns the first elements of the list name.By de…...

第四百一十回

文章目录 1. 概念介绍2. 方法与细节2.1 获取方法2.2 使用细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取当前系统语言"相关的内容&#xff0c;本章回中将介绍如何获取时间戳.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…...

程序员的README——编写可维护的代码(一)

用户行为不可预测&#xff0c;网络不可靠&#xff0c;事情总会出错。生产环境下的软件必须一直保持可用状态。 编写可维护的代码有助于你应对不可预见的情况&#xff0c;可维护的代码有内置的保护、诊断和控制。 切记通过安全和有弹性的编码实践进行防御式编程来保护你的系统&a…...

数据库管理-第160期 Oracle Vector DB AI-11(20240312)

数据库管理160期 2024-03-12 数据库管理-第160期 Oracle Vector DB & AI-11&#xff08;20240312&#xff09;1 向量的函数操作to_vector()将vector转换为标准值vector_norm()vector_dimension_count()vector_dimension_format() 2 将向量转换为字符串或CLOBvector_seriali…...

(C++进阶)boost库笔记

目录 1、boost::function 1.1 概述 1.2 boost包装器和C11包装器对比 1.2、代码示例 1、boost::function 1.1 概述 boost::function 是 Boost 库中提供的一个通用函数对象包装器&#xff0c;它可以存储指向任何可调用对象的指针&#xff0c;并且可以在任何时候通过 operat…...

MapReduce面试重点

文章目录 1. 简述MapReduce整个流程2. join原理 1. 简述MapReduce整个流程 数据划分(Input Splitting)&#xff1a;开始时&#xff0c;输入数据被分割成逻辑上的小块&#xff0c;每个块被称为Input Split。 映射(Map)&#xff1a;每个Input Split 由一个或多个Map任务处理&…...

C语言简单题(7)从主函数中输入10个等长字符串,用一个函数对他们排序,然后在主函数输出这10个已排好序的字符串

从主函数中输入10个等长字符串&#xff0c;用一个函数对他们排序&#xff0c;然后在主函数输出这10个已排好序的字符串 /* 从主函数中输入10个等长字符串&#xff0c;用一个函数对他们排序&#xff0c;然后在主函数输出这10个已排好序的字符串 */ #include<stdio.h> …...

光伏科普|太阳能光伏发电应用场景有哪些?

太阳能光伏发电的应用领域其实非常广泛&#xff0c;很多人会不相信&#xff0c;但在我们的日常生活中随处可见太阳能光伏产业&#xff0c;本文将详细介绍其应用场景有哪些。 一、工业领域厂房 太阳能光伏发电作为一种清洁、可再生的能源&#xff0c;安装在工业领域厂房&#…...

Go 构建高效的二叉搜索树联系簿

引言 树是一种重要的数据结构&#xff0c;而二叉搜索树&#xff08;BST&#xff09;则是树的一种常见形式。在本文中&#xff0c;我们将学习如何构建一个高效的二叉搜索树联系簿&#xff0c;以便快速插入、搜索和删除联系人信息。 介绍二叉搜索树 二叉搜索树是一种有序的二叉…...

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的交通信号灯识别系统(深度学习+UI界面+训练数据集+Python代码)

摘要&#xff1a;本研究详细介绍了一种采用深度学习技术的交通信号灯识别系统&#xff0c;该系统集成了最新的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5等早期算法进行了性能评估对比。该系统能够在各种媒介——包括图像、视频文件、实时视频流及批量文件中——准确地…...

以太坊开发学习-solidity(三)函数类型

目录 函数类型 函数类型 solidity官方文档里把函数归到数值类型 函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量&#xff0c; 也可以将一个函数作为参数进行传递&#xff0c;还能在函数调用中返回函数类型变量。 函数类型有两类&#xff1a;- 内部&…...

教你把公司吃干抹净、榨干带走

大家好&#xff1a; 衷心希望各位点赞。 您的问题请留在评论区&#xff0c;我会及时回答 正文 打工人一定要做到够自私&#xff0c;把公司的一切为我所用&#xff0c;你要知道闷头打工是没有出路的。聪明的人会以最快的速度榨干带走公司的一切资源、人脉、技能&#xff0c;为…...

开发指南007-导出Excel

平台上开发导出Excel比过去的单体架构要复杂些&#xff0c;因为前端和后台不在一个进程空间里。 后台的操作是先生成excel文件&#xff0c;技术路线是jxl <dependency><groupId>net.sourceforge.jexcelapi</groupId><artifactId>jxl</artifactId&g…...

滑块验证码

1.这里针对滑块验证给了一个封装的组件verifition&#xff0c;使用直接可以调用 2.组件目录 3.每个文件的内容 3.1 Api文件中只有一个index.js文件&#xff0c;用来存放获取滑块和校验滑块结果的api import request from /router/axios//获取验证图片 export function reqGe…...

cmd常用指令

cmd全称Command Prompt&#xff0c;中文译为命令提示符。 命令提示符是在操作系统中&#xff0c;提示进行命令输入的一种工作提示符。 在不同的操作系统环境下&#xff0c;命令提示符各不相同。 在windows环境下&#xff0c;命令行程序为cmd.exe&#xff0c;是一个32位的命令…...

【嵌入式DIY实例】-DIY手势识别和颜色识别(基于APDS9960)

DIY手势识别和颜色识别(基于APDS9960) 文章目录 DIY手势识别和颜色识别(基于APDS9960)1、硬件准备2、APDS9960 手势识别传感器介绍3、硬件接线4、代码实现4.1 手势识别4.2 颜色识别4.3 趋近感应代码5、综合实例代码在本文中,我们将介绍 APDS9960 手势、RGB 和接近传感器与…...

python 直方图

python可以调用hist方法绘制直方图。 import matplotlib.pyplot as plt import numpy as np; plt.rcParams["font.family"]["SimHei"] # 确保图中中文字体正确显示 x[0.1,0.2,0.3,0.4,0.5,0.6,0.1,0.2,0.2,0.2] plt.xlabel(满意程度) plt.ylabel(频数) …...

如何在数据库中使用sql语言插入数据

在SQL中&#xff0c;你可以使用INSERT INTO语句来添加数据到数据库表中。以下是一个基本示例&#xff0c;说明如何向表中插入数据&#xff1a; 假设你有一个名为students的表&#xff0c;它有以下字段&#xff1a;id, name, age 和 grade。 CREATE TABLE students ( id INT P…...

JVM的双亲委派模型和垃圾回收机制

jvm的作用是解释执行java字节码.java的跨平台就是靠jvm实现的.下面看看一个java程序的执行流程. 1. jvm中的内存区域划分 jvm也是一个进程,进程在运行过程中,要行操作系统申请一些资源.这些内存空间就支撑了后续java程序的执行. jvm从系统申请了一大块内存,这块内存在java程序使…...

ThreadLocal-内存泄露问题

ThreadLocal概述 ThreadLocal是多线程中对于解决线程安全的一个操作类&#xff0c;它会为每个线程都分配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时实现了线程内的资源共享案例&#xff1a;使用JDBC操作数据库时&#xff0c;会将每一个线程的Conn…...

ISIS默认层级实验简述

ISIS被划分为三个层级&#xff1a;Level 1、Level 2和Level 1-2。 默认情况下&#xff0c;ISIS路由器属于level 1-2,是指同时支持Level 1和Level 2的路由器。路由器既可以在同一个自治系统内部进行路由选择&#xff0c;也可以将路由信息传递到其他自治系统。 实验拓扑图&#…...

在Flutter中创建自定义的左对齐TabBar组件

在Flutter应用程序中&#xff0c;TabBar是一种常见的UI模式&#xff0c;用于在不同的标签页之间进行导航。然而&#xff0c;默认情况下&#xff0c;Flutter的TabBar在水平方向上是居中对齐的。本文将介绍如何创建一个自定义的左对齐TabBar组件&#xff0c;以满足特定的布局需求…...

【Python】继承会遇到的问题

单继承和多继承在python中的区别和应用场景 单继承指的是一个子类只继承自一个父类。这简化了继承关系&#xff0c;使得代码易于理解和维护。大多数情况下&#xff0c;单继承足以处理常见的场景&#xff0c;如扩展基类的功能或者覆盖某些方法。多重继承允许在一个类同时继承多个…...

相机模型Omnidirectional Camera(全方位摄像机)

1. 背景 大多数商用相机都可以描述为针孔相机&#xff0c;通过透视投影进行建模。然而&#xff0c;有些投影系统的几何结构无法使用传统针孔模型来描述&#xff0c;因为成像设备引入了非常高的失真。其中一些系统就是全方位摄像机。 有几种方法可以制作全向相机。屈光照相机(D…...

论文阅读——Align before Fuse

Align before Fuse: Vision and Language Representation Learning with Momentum Distillation image-text contrastive learning(ITC)用在单模态&#xff0c;masked language modeling (MLM) and image-text matching (ITM) 用在多模态。 单模态编码器的表示上引入了中间图像…...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Rating)

提供在给定范围内选择评分的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Rating(options?: { rating: number, indicator?: boolean }) 从API version 9开始&#…...

Unity中的网格创建和曲线变形

Unity中的网格创建和曲线变形 3D贝塞尔曲线变形贝塞尔曲线基础线性公式二次方公式三次方公式 Unity 实现3D贝塞尔曲线变形准备工作脚本概述变量定义 变量解析函数解析 获取所有子节点GetAllChildren 获取所有子节点UpdateBezierBend 控制点更新CalculateBezier Bezier 曲线公式…...