diff --git a/BUILD.gn b/BUILD.gn index 46e1779..8062143 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -168,6 +168,13 @@ config("os_config") { } } +config("public") { + include_dirs = [ + "//kernel/uniproton/src/arch/include", + "//kernel/uniproton/src/core/kernel/include", + ] +} + ohos_static_library("notice") { license_file = "./NOTICE" } @@ -216,6 +223,9 @@ static_library("libkernel") { deps = [ "//third_party/bounds_checking_function:libsec_static" ] deps += [ "//third_party/musl/porting/uniproton/kernel:kernel" ] + if (defined(DRIVERS_HDF)) { + deps += [ HDFTOPDIR ] + } } group("kernel") { diff --git a/src/Kconfig b/src/Kconfig index 059f1eb..caee22c 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -8,4 +8,5 @@ source "om/Kconfig" source "security/Kconfig" source "fs/Kconfig" source "net/Kconfig" +osource "../../../drivers/hdf_core/adapter/khdf/uniproton/Kconfig" source "utility/Kconfig" diff --git a/src/include/uapi/prt_mem.h b/src/include/uapi/prt_mem.h index e5e0860..6fd905c 100644 --- a/src/include/uapi/prt_mem.h +++ b/src/include/uapi/prt_mem.h @@ -202,6 +202,32 @@ enum MemAlign { */ extern void *PRT_MemAlloc(U32 mid, U8 ptNo, U32 size); +/* + * @brief 向已创建的指定分区申请内存。 + * + * @par 描述 + *
  • 在分区号为ptNo的分区中,申请大小为size的内存,且申请到的内存地址按照指定的字节数对齐。
  • + * @attention + * + * + * @param mid [IN] 类型#U32,申请的模块号。 + * @param ptNo [IN] 类型#U8,分区号,范围[0,#OS_MEM_MAX_PT_NUM+2)。 + * @param size [IN] 类型#U32,申请的大小。 + * @param boundary [IN] 类型#U32,申请到的内存地址的对齐字节数。 + * + * @retval #NULL 0,申请失败。 + * @retval #!NULL 内存首地址值。 + * @par 依赖 + * + * @see PRT_MemFree + */ +extern void *PRT_MemAllocAlign(U32 mid, U8 ptNo, U32 size, U32 boundary); + /* * @brief 释放申请的内存。 * diff --git a/src/mem/fsc/prt_fscmem.c b/src/mem/fsc/prt_fscmem.c index a7c3029..7412b2f 100644 --- a/src/mem/fsc/prt_fscmem.c +++ b/src/mem/fsc/prt_fscmem.c @@ -15,11 +15,12 @@ #include "prt_task_external.h" #include "prt_fscmem_internal.h" -#define OWNER_HWI 0xffff -#define OWNER_SYS 0xeeee /* 判断初始化内存地址和大小是否为4字节对齐 */ #define OS_MEM_GETBIT(addr) (addr & (U32)(sizeof(U32) - 1)) +#define OS_MEM_IS_POW_TWO(value) ((((uintptr_t)(value)) & ((uintptr_t)(value) - 1)) == 0) +#define OS_MEM_IS_ALIGNED(a, b) (!(((uintptr_t)(a)) & (((uintptr_t)(b)) - 1))) + OS_SEC_BSS struct TagMemFuncLib g_memArithAPI; /* 算法对应API */ OS_SEC_BSS struct TagFscMemCtrl g_fscMemNodeList[OS_FSC_MEM_LAST_IDX]; OS_SEC_BSS U32 g_fscMemBitMap = 1; @@ -68,32 +69,38 @@ OS_SEC_TEXT struct TagFscMemCtrl *OsFscMemSearch(U32 size, U32 *idx) return currBlk; } -OS_SEC_TEXT void *OsFscMemAlloc(U32 mid, U32 size) +OS_SEC_TEXT void *OsFscMemAllocInner(U32 mid, U32 size, uintptr_t align) { U32 idx; + U32 allocSize; U32 *blkTailMagic = NULL; + uintptr_t usrAddr; struct TagFscMemCtrl *plotBlk = NULL; struct TagFscMemCtrl *currBlk = NULL; struct TagFscMemCtrl *nextBlk = NULL; + (void)mid; if (size == 0) { OS_REPORT_ERROR(OS_ERRNO_MEM_ALLOC_SIZE_ZERO); return NULL; - } else if (size >= ((OS_FSC_MEM_MAXVAL - OS_FSC_MEM_USED_HEAD_SIZE) - OS_FSC_MEM_TAIL_SIZE)) { + } + + /* 由于已经按OS_FSC_MEM_SIZE_ALIGN字节对齐,最大可能补齐的大小是align - OS_FSC_MEM_SIZE_ALIGN */ + allocSize = ALIGN(size, OS_FSC_MEM_SIZE_ALIGN) + (align - OS_FSC_MEM_SIZE_ALIGN) + + OS_FSC_MEM_USED_HEAD_SIZE + OS_FSC_MEM_TAIL_SIZE; + if ((allocSize < size) || allocSize >= ((OS_FSC_MEM_MAXVAL - OS_FSC_MEM_USED_HEAD_SIZE) - OS_FSC_MEM_TAIL_SIZE)) { OS_REPORT_ERROR(OS_ERRNO_MEM_ALLOC_SIZETOOLARGE); return NULL; } - size = ALIGN(size, OS_FSC_MEM_SIZE_ALIGN) + OS_FSC_MEM_USED_HEAD_SIZE + OS_FSC_MEM_TAIL_SIZE; - - currBlk = OsFscMemSearch(size, &idx); + currBlk = OsFscMemSearch(allocSize, &idx); if (currBlk == NULL) { return NULL; } /* 找到足够空间的空闲链表,并对其进行分割 */ - if (OS_FSC_MEM_SZGET(currBlk) >= (size + OS_FSC_MEM_MIN_SIZE)) { - currBlk->size -= (U16)size; + if (OS_FSC_MEM_SZGET(currBlk) >= (allocSize + OS_FSC_MEM_MIN_SIZE)) { + currBlk->size -= allocSize; /* 调整链表 */ if (idx != OS_FSC_MEM_SZ2IDX(currBlk->size)) { @@ -103,7 +110,7 @@ OS_SEC_TEXT void *OsFscMemAlloc(U32 mid, U32 size) plotBlk = (struct TagFscMemCtrl *)((uintptr_t)currBlk + (uintptr_t)currBlk->size); plotBlk->prevSize = currBlk->size; - plotBlk->size = (U16)size; + plotBlk->size = allocSize; currBlk = plotBlk; } else { @@ -118,19 +125,26 @@ OS_SEC_TEXT void *OsFscMemAlloc(U32 mid, U32 size) blkTailMagic = (U32 *)((uintptr_t)currBlk + (uintptr_t)currBlk->size - (uintptr_t)OS_FSC_MEM_TAIL_SIZE); *blkTailMagic = OS_FSC_MEM_TAIL_MAGIC; - if (mid == 0) { - if ((UNI_FLAG & OS_FLG_BGD_ACTIVE) == 0) { - currBlk->prev = (struct TagFscMemCtrl *)OWNER_SYS; - } else if ((UNI_FLAG & OS_FLG_HWI_ACTIVE) != 0) { - currBlk->prev = (struct TagFscMemCtrl *)OWNER_HWI; - } else { - currBlk->prev = (struct TagFscMemCtrl *)(uintptr_t)(RUNNING_TASK->taskPid); - } - } else { - currBlk->prev = (struct TagFscMemCtrl *)OWNER_SYS; - } + // currBlk->prev 复用为内存对齐的偏移地址 + currBlk->prev = 0; + usrAddr = (((uintptr_t)currBlk + OS_FSC_MEM_SLICE_HEAD_SIZE + align - 1) & ~(align - 1)); + OsMemSetHeadAddr(usrAddr, ((uintptr_t)currBlk + OS_FSC_MEM_SLICE_HEAD_SIZE)); - return (void *)((uintptr_t)currBlk + (uintptr_t)OS_FSC_MEM_USED_HEAD_SIZE); + return (void *)usrAddr; +} + +OS_SEC_TEXT void *OsFscMemAlloc(U32 mid, U32 size) +{ + return OsFscMemAllocInner(mid, size, OS_FSC_MEM_SIZE_ALIGN); +} + +OS_SEC_TEXT void *OsFscMemAllocAlign(U32 mid, U32 size, U32 boundary) +{ + if ((boundary == 0) || !OS_MEM_IS_POW_TWO(boundary) || !OS_MEM_IS_ALIGNED(boundary, sizeof(void *))) { + OS_REPORT_ERROR(OS_ERRNO_MEM_ALLOC_ALIGNPOW_INVALID); + return NULL; + } + return OsFscMemAllocInner(mid, size, boundary); } OS_SEC_TEXT U32 OsFscMemFree(void *addr) @@ -145,7 +159,7 @@ OS_SEC_TEXT U32 OsFscMemFree(void *addr) return OS_ERRNO_MEM_FREE_ADDR_INVALID; } - currBlk = (struct TagFscMemCtrl *)((uintptr_t)addr - (uintptr_t)OS_FSC_MEM_USED_HEAD_SIZE); + currBlk = (struct TagFscMemCtrl *)OsMemGetHeadAddr((uintptr_t)addr); blkSize = currBlk->size; if ((currBlk->next != OS_FSC_MEM_MAGIC_USED) || (currBlk->size == 0)) { @@ -201,8 +215,7 @@ OS_SEC_TEXT void *OsMemAlloc(enum MoudleId mid, U8 ptNo, U32 size) OS_SEC_TEXT void *OsMemAllocAlign(U32 mid, U8 ptNo, U32 size, enum MemAlign alignPow) { (void)ptNo; - (void)alignPow; - return OsFscMemAlloc(mid, size); + return OsFscMemAllocInner(mid, size, (1U << (U32)alignPow)); } /* @@ -270,6 +283,7 @@ OS_SEC_TEXT U32 OsFscMemInit(U32 addr, U32 size) nextBlk->size = 0; g_memArithAPI.alloc = OsFscMemAlloc; + g_memArithAPI.allocAlign = OsFscMemAllocAlign; g_memArithAPI.free = OsFscMemFree; g_osMemAlloc = OsMemAlloc; diff --git a/src/mem/prt_mem.c b/src/mem/prt_mem.c index 319bf01..a23688d 100644 --- a/src/mem/prt_mem.c +++ b/src/mem/prt_mem.c @@ -28,6 +28,20 @@ OS_SEC_TEXT void *PRT_MemAlloc(U32 mid, U8 ptNo, U32 size) return addr; } +OS_SEC_TEXT void *PRT_MemAllocAlign(U32 mid, U8 ptNo, U32 size, U32 boundary) +{ + void *addr = NULL; + uintptr_t intSave; + + (void)ptNo; + + intSave = PRT_HwiLock(); + addr = g_memArithAPI.allocAlign(mid, size, boundary); + PRT_HwiRestore(intSave); + + return addr; +} + OS_SEC_TEXT U32 PRT_MemFree(U32 mid, void *addr) { U32 ret; diff --git a/src/mem/prt_mem_internal.h b/src/mem/prt_mem_internal.h index e6ee1ed..68506a2 100644 --- a/src/mem/prt_mem_internal.h +++ b/src/mem/prt_mem_internal.h @@ -28,12 +28,16 @@ /* 申请一个内存块 */ typedef void *(*MemAllocFunc)(U32 mid, U32 size); +/* 申请size字节并返回指向已分配内存的指针,内存地址将是boundary的倍数 */ +typedef void *(*MemAllocAlignFunc)(U32 mid, U32 size, U32 boundary); + /* 释放一个内存块 */ typedef U32 (*MemFreeFunc)(void *addr); struct TagMemFuncLib { void *addr; /* 分区起始地址 */ MemAllocFunc alloc; /* 申请一个内存块 */ + MemAllocAlignFunc allocAlign; /* 申请size字节并返回指向已分配内存的指针,内存地址将是boundary的倍数 */ MemFreeFunc free; /* 释放一个内存块 */ }; diff --git a/uniproton.gni b/uniproton.gni index f018d5b..955cab8 100644 --- a/uniproton.gni +++ b/uniproton.gni @@ -13,26 +13,121 @@ import("//build/lite/config/component/lite_component.gni") product_config_file = "${ohos_build_type}.config" -product_config_file = rebase_path(product_config_file, "", "$product_path/kernel_configs") +product_config_file = + rebase_path(product_config_file, "", "$product_path/kernel_configs") print("product_config_file:", product_config_file) MENUCONFIG_H = rebase_path("$root_out_dir/config.h") -exec_script("//build/lite/run_shell_cmd.py", - [ "env" + " CONFIG_=" + " KCONFIG_CONFIG_HEADER='y=true'" + - " KCONFIG_CONFIG=$product_config_file" + - " BOARD_COMPANY=$device_company" + - " DEVICE_PATH=$device_path" + " srctree=" + rebase_path("./src") + - " genconfig" + " --header-path $MENUCONFIG_H" + - " --file-list kconfig_files.txt" + - " --env-list kconfig_env.txt" + " --config-out config.gni" ], - "", - [ product_config_file ]) +exec_script( + "//build/lite/run_shell_cmd.py", + [ "env" + " CONFIG_=" + " KCONFIG_CONFIG_HEADER='y=true'" + + " KCONFIG_CONFIG=$product_config_file" + + " BOARD_COMPANY=$device_company" + " DEVICE_PATH=$device_path" + + " srctree=" + rebase_path("./src") + " genconfig" + + " --header-path $MENUCONFIG_H" + " --file-list kconfig_files.txt" + + " --env-list kconfig_env.txt" + " --config-out config.gni" ], + "", + [ product_config_file ]) import("$root_out_dir/config.gni") OSTOPDIR = "//kernel/uniproton/src" OSTHIRDPARTY = "//third_party" +HDFTOPDIR = "//drivers/hdf_core/adapter/khdf/uniproton" + +template("kernel_module") { + build_gn = rebase_path("BUILD.gn") + print("build_gn is $build_gn") + cmd = "grep -c '^\s*\(kernel_module\|hdf_driver\)\s*(\s*\S*\s*)\s*{\s*\$' $build_gn" + modules_count = exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") + if (modules_count == 1) { + auto_config = true + } + + cmd = "if grep -q '^\s*\(config\s*(\s*\"public\"\s*)\|module_group\s*(\s*\"\S*\"\s*)\)\s*{\s*\$' $build_gn; then echo true; else echo false; fi" + has_public_config = + exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") + if (!has_public_config && defined(auto_config)) { + config("public") { + configs = [] + } + } + + current_dir_name = get_path_info(rebase_path("."), "file") + if (target_name != current_dir_name) { + cmd = "if grep -q '^\s*\(module_group\|group\)\s*(\s*\"$current_dir_name\"\s*)\s*{\s*\$' $build_gn; then echo true; else echo false; fi" + has_current_dir_group = + exec_script("//build/lite/run_shell_cmd.py", [ cmd ], "value") + if (!has_current_dir_group && defined(auto_config)) { + module_name = target_name + group(current_dir_name) { + public_deps = [ ":$module_name" ] + } + } + } + + if (defined(invoker.module_switch) && !invoker.module_switch) { + group(target_name) { + not_needed(invoker, "*") + } + } else { + source_set(target_name) { + public_configs = [] + forward_variables_from(invoker, "*", [ "configs" ]) + configs += invoker.configs + if (has_public_config) { + included_public_config = false + foreach(cfg, public_configs) { + what = "label_no_toolchain" + if (get_label_info(cfg, what) == get_label_info(":public", what)) { + included_public_config = true + included_public_config = false + } + } + if (!included_public_config) { + public_configs += [ ":public" ] + } + } + } + } + not_needed([ "auto_config" ]) +} + +template("config") { + config(target_name) { + if (defined(invoker.module_switch) && !invoker.module_switch && + target_name == "public") { + not_needed(invoker, "*") + forward_variables_from(invoker, [ "configs" ]) + } else { + forward_variables_from(invoker, "*") + } + } +} + +template("module_group") { + assert(defined(invoker.modules), "modules are must") + group(target_name) { + deps = [] + foreach(m, invoker.modules) { + deps += [ m ] + } + if (defined(invoker.deps)) { + deps += invoker.deps + } + } + config("public") { + configs = [] + foreach(m, invoker.modules) { + configs += [ "$m:public" ] + } + if (defined(invoker.configs)) { + configs += invoker.configs + } + } +} + KERNEL_BASE_INCLUDE_DIRS = [ "$OSTOPDIR/arch/include", "$OSTOPDIR/config", @@ -76,9 +171,7 @@ KERNEL_SWTMR_SOURCES = [ "$OSTOPDIR/core/kernel/timer/swtmr/prt_swtmr_minor.c", ] -KERNEL_IPC_EVENT_SOURCES = [ - "$OSTOPDIR/core/ipc/event/prt_event.c", -] +KERNEL_IPC_EVENT_SOURCES = [ "$OSTOPDIR/core/ipc/event/prt_event.c" ] KERNEL_IPC_QUEUE_SOURCES = [ "$OSTOPDIR/core/ipc/queue/prt_queue.c", @@ -95,7 +188,7 @@ KERNEL_IPC_SEM_SOURCES = [ KERNEL_MEM_SOURCES = [ "$OSTOPDIR/mem/prt_mem.c", - "$OSTOPDIR/mem/fsc/prt_fscmem.c" + "$OSTOPDIR/mem/fsc/prt_fscmem.c", ] KERNEL_OM_SOURCES = [ @@ -113,13 +206,11 @@ KERNEL_OM_CPUP_SOURCES = [ "$OSTOPDIR/om/cpup/prt_cpup_warn.c", ] -KERNEL_SECURITY_SOURCES = [ - "$OSTOPDIR/security/rnd/prt_rnd_set.c" -] +KERNEL_SECURITY_SOURCES = [ "$OSTOPDIR/security/rnd/prt_rnd_set.c" ] KERNEL_UTILITY_SOURCES = [ "$OSTOPDIR/utility/lib/prt_lib_math64.c", - "$OSTOPDIR/utility/lib/prt_lib_version.c" + "$OSTOPDIR/utility/lib/prt_lib_version.c", ] KERNEL_FS_INCLUDE_DIRS = [ @@ -139,9 +230,7 @@ KERNEL_FS_SOURCES = [ "$OSTOPDIR/fs/littlefs/lfs_adapter.c", ] -KERNEL_LWIP_INCLUDE_DIRS = [ - "$OSTOPDIR/net/lwip-2.1/include" -] +KERNEL_LWIP_INCLUDE_DIRS = [ "$OSTOPDIR/net/lwip-2.1/include" ] KERNEL_LWIP_SOURCES = [ "$OSTOPDIR/net/lwip-2.1/src/driverif.c", @@ -162,9 +251,7 @@ ARCH_ARMVM7_M_SOURCES = [ "$OSTOPDIR/arch/cpu/armv7-m/common/prt_port.c", ] -ARCH_ARMVM7_M_INCLUDE_DIRS = [ - "$OSTOPDIR/arch/cpu/armv7-m/common", -] +ARCH_ARMVM7_M_INCLUDE_DIRS = [ "$OSTOPDIR/arch/cpu/armv7-m/common" ] ARCH_CORTEX_M4_SOURCES = [ "$OSTOPDIR/arch/cpu/armv7-m/cortex-m4/prt_dispatch.S", @@ -174,6 +261,18 @@ ARCH_CORTEX_M4_SOURCES = [ "$OSTOPDIR/arch/cpu/armv7-m/cortex-m4/prt_vector.S", ] -ARCH_CORTEX_M4_INCLUDE_DIRS = [ - "$OSTOPDIR/arch/cpu/armv7-m/cortex-m4", -] +ARCH_CORTEX_M4_INCLUDE_DIRS = [ "$OSTOPDIR/arch/cpu/armv7-m/cortex-m4" ] + +set_defaults("kernel_module") { + configs = [ + "//kernel/uniproton:os_config", + "//kernel/uniproton:kernel_config", + "//kernel/uniproton:public", + ] + visibility = [ + ":*", + "..:*", + "../..:*", + "//kernel/uniproton:*", + ] +}