Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
berryhaxby
注释鸿蒙内核源码
提交
1b01ca35
注释鸿蒙内核源码
项目概览
berryhaxby
/
注释鸿蒙内核源码
与 Fork 源项目一致
Fork自
鸿蒙内核源码分析 / 注释鸿蒙内核源码
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
注释鸿蒙内核源码
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1b01ca35
编写于
10月 25, 2020
作者:
鸿蒙内核源码分析
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
鸿蒙源码分析系列篇
https://blog.csdn.net/kuangyufei
https://my.oschina.net/u/3751245
上级
bb1b1f85
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
95 addition
and
95 deletion
+95
-95
arch/arm/arm/src/los_hw.c
arch/arm/arm/src/los_hw.c
+2
-2
kernel/base/core/los_process.c
kernel/base/core/los_process.c
+24
-24
kernel/base/core/los_task.c
kernel/base/core/los_task.c
+39
-39
kernel/base/include/los_process_pri.h
kernel/base/include/los_process_pri.h
+1
-1
kernel/base/include/los_task_pri.h
kernel/base/include/los_task_pri.h
+7
-7
kernel/extended/dynload/src/los_exec_elf.c
kernel/extended/dynload/src/los_exec_elf.c
+14
-14
syscall/process_syscall.c
syscall/process_syscall.c
+8
-8
未找到文件。
arch/arm/arm/src/los_hw.c
浏览文件 @
1b01ca35
...
...
@@ -127,7 +127,7 @@ LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *
(
VOID
)
memcpy_s
(
childTaskCB
->
stackPointer
,
sizeof
(
TaskContext
),
cloneStack
,
sizeof
(
TaskContext
));
context
->
R
[
0
]
=
0
;
}
//用户栈初始化
//用户
任务使用
栈初始化
LITE_OS_SEC_TEXT_INIT
VOID
OsUserTaskStackInit
(
TaskContext
*
context
,
TSK_ENTRY_FUNC
taskEntry
,
UINTPTR
stack
)
{
LOS_ASSERT
(
context
!=
NULL
);
...
...
@@ -139,7 +139,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_F
#endif
context
->
R
[
0
]
=
stack
;
//栈指针给r0寄存器
context
->
SP
=
TRUNCATE
(
stack
,
LOSCFG_STACK_POINT_ALIGN_SIZE
);
//异常模式所专用的堆栈 segment fault 输出回溯信息
context
->
LR
=
0
;
//保存子程序返回地址 a call b ,在b中保存 a地址
context
->
LR
=
0
;
//保存子程序返回地址
例如
a call b ,在b中保存 a地址
context
->
PC
=
(
UINTPTR
)
taskEntry
;
//入口函数
}
...
...
kernel/base/core/los_process.c
浏览文件 @
1b01ca35
...
...
@@ -127,7 +127,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 sta
}
else
{
OS_PROCESS_PRI_QUEUE_ENQUEUE
(
processCB
);
//入进程入g_priQueueList就绪队列
}
processCB
->
processStatus
&=
~
(
status
|
OS_PROCESS_STATUS_PEND
);
processCB
->
processStatus
&=
~
(
status
|
OS_PROCESS_STATUS_PEND
);
//去掉外传标签和阻塞标签
processCB
->
processStatus
|=
OS_PROCESS_STATUS_READY
;
}
else
{
LOS_ASSERT
(
!
(
processCB
->
processStatus
&
OS_PROCESS_STATUS_PEND
));
...
...
@@ -739,10 +739,10 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U
LOS_PhysPagesFreeContiguous
(
ttb
,
1
);
//释放物理页,4K
return
LOS_EAGAIN
;
}
processCB
->
vmSpace
=
space
;
LOS_ListAdd
(
&
processCB
->
vmSpace
->
archMmu
.
ptList
,
&
(
vmPage
->
node
));
processCB
->
vmSpace
=
space
;
//设为进程虚拟空间
LOS_ListAdd
(
&
processCB
->
vmSpace
->
archMmu
.
ptList
,
&
(
vmPage
->
node
));
//将空间映射页表挂在 空间的mmu L1页表, L1为表头
}
else
{
processCB
->
vmSpace
=
LOS_GetKVmSpace
();
processCB
->
vmSpace
=
LOS_GetKVmSpace
();
//内核共用一个虚拟空间,内核进程 常驻内存
}
#ifdef LOSCFG_SECURITY_VID
...
...
@@ -762,7 +762,7 @@ STATIC UINT32 OsInitPCB(LosProcessCB *processCB, UINT32 mode, UINT16 priority, U
return
LOS_OK
;
}
//创建用户
#ifdef LOSCFG_SECURITY_CAPABILITY
STATIC
User
*
OsCreateUser
(
UINT32
userID
,
UINT32
gid
,
UINT32
size
)
{
...
...
@@ -1540,7 +1540,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
LOS_VmSpaceFree
(
oldSpace
);
return
LOS_OK
;
}
//进程层面的开始执行, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
LITE_OS_SEC_TEXT
UINT32
OsExecStart
(
const
TSK_ENTRY_FUNC
entry
,
UINTPTR
sp
,
UINTPTR
mapBase
,
UINT32
mapSize
)
{
LosProcessCB
*
processCB
=
NULL
;
...
...
@@ -1552,36 +1552,36 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
return
LOS_NOK
;
}
if
((
sp
==
0
)
||
(
LOS_Align
(
sp
,
LOSCFG_STACK_POINT_ALIGN_SIZE
)
!=
sp
))
{
if
((
sp
==
0
)
||
(
LOS_Align
(
sp
,
LOSCFG_STACK_POINT_ALIGN_SIZE
)
!=
sp
))
{
//对齐
return
LOS_NOK
;
}
if
((
mapBase
==
0
)
||
(
mapSize
==
0
)
||
(
sp
<=
mapBase
)
||
(
sp
>
(
mapBase
+
mapSize
)))
{
if
((
mapBase
==
0
)
||
(
mapSize
==
0
)
||
(
sp
<=
mapBase
)
||
(
sp
>
(
mapBase
+
mapSize
)))
{
//参数检查
return
LOS_NOK
;
}
SCHEDULER_LOCK
(
intSave
);
processCB
=
OsCurrProcessGet
();
taskCB
=
OsCurrTaskGet
();
SCHEDULER_LOCK
(
intSave
);
//拿自旋锁
processCB
=
OsCurrProcessGet
();
//获取当前进程
taskCB
=
OsCurrTaskGet
();
//获取当前任务
processCB
->
threadGroupID
=
taskCB
->
taskID
;
taskCB
->
userMapBase
=
mapBase
;
taskCB
->
userMapSize
=
mapSize
;
taskCB
->
taskEntry
=
(
TSK_ENTRY_FUNC
)
entry
;
processCB
->
threadGroupID
=
taskCB
->
taskID
;
//threadGroupID是进程的主线程ID,也就是应用程序 main函数线程
taskCB
->
userMapBase
=
mapBase
;
//任务栈底地址
taskCB
->
userMapSize
=
mapSize
;
//任务栈大小
taskCB
->
taskEntry
=
(
TSK_ENTRY_FUNC
)
entry
;
//任务的入口函数
taskContext
=
(
TaskContext
*
)
OsTaskStackInit
(
taskCB
->
taskID
,
taskCB
->
stackSize
,
(
VOID
*
)
taskCB
->
topOfStack
,
FALSE
);
OsUserTaskStackInit
(
taskContext
,
taskCB
->
taskEntry
,
sp
);
SCHEDULER_UNLOCK
(
intSave
);
taskContext
=
(
TaskContext
*
)
OsTaskStackInit
(
taskCB
->
taskID
,
taskCB
->
stackSize
,
(
VOID
*
)
taskCB
->
topOfStack
,
FALSE
);
//创建任务上下文
OsUserTaskStackInit
(
taskContext
,
taskCB
->
taskEntry
,
sp
);
//用户进程任务栈初始化
SCHEDULER_UNLOCK
(
intSave
);
//解锁
return
LOS_OK
;
}
//用户进程开始初始化
STATIC
UINT32
OsUserInitProcessStart
(
UINT32
processID
,
TSK_INIT_PARAM_S
*
param
)
{
UINT32
intSave
;
INT32
taskID
;
INT32
ret
;
taskID
=
OsCreateUserTask
(
processID
,
param
);
taskID
=
OsCreateUserTask
(
processID
,
param
);
//创建一个用户态任务
if
(
taskID
<
0
)
{
return
LOS_NOK
;
}
...
...
@@ -1657,7 +1657,7 @@ ERROR:
OsDeInitPCB
(
processCB
);
//删除PCB块
return
ret
;
}
//拷贝用户信息 直接用memcpy_s
STATIC
UINT32
OsCopyUser
(
LosProcessCB
*
childCB
,
LosProcessCB
*
parentCB
)
{
#ifdef LOSCFG_SECURITY_CAPABILITY
...
...
@@ -1671,7 +1671,7 @@ STATIC UINT32 OsCopyUser(LosProcessCB *childCB, LosProcessCB *parentCB)
#endif
return
LOS_OK
;
}
//任务初始化时拷贝任务信息
STATIC
VOID
OsInitCopyTaskParam
(
LosProcessCB
*
childProcessCB
,
const
CHAR
*
name
,
UINTPTR
entry
,
UINT32
size
,
TSK_INIT_PARAM_S
*
childPara
)
{
...
...
@@ -1679,9 +1679,9 @@ STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name,
UINT32
intSave
;
SCHEDULER_LOCK
(
intSave
);
mainThread
=
OsCurrTaskGet
();
mainThread
=
OsCurrTaskGet
();
//获取当前task,注意变量名从这里也可以看出 thread 和 task 是一个概念,只是内核常说task,上层应用说thread ,概念的映射.
if
(
OsProcessIsUserMode
(
childProcessCB
))
{
if
(
OsProcessIsUserMode
(
childProcessCB
))
{
//用户模式进程
childPara
->
pfnTaskEntry
=
mainThread
->
taskEntry
;
childPara
->
uwStackSize
=
mainThread
->
stackSize
;
childPara
->
userParam
.
userArea
=
mainThread
->
userArea
;
...
...
kernel/base/core/los_task.c
浏览文件 @
1b01ca35
...
...
@@ -1838,7 +1838,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID,
return
LOS_OK
;
}
//创建一个用户任务
LITE_OS_SEC_TEXT_INIT
INT32
OsCreateUserTask
(
UINT32
processID
,
TSK_INIT_PARAM_S
*
initParam
)
{
LosProcessCB
*
processCB
=
NULL
;
...
...
@@ -1851,32 +1851,32 @@ LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S
return
ret
;
}
initParam
->
uwStackSize
=
OS_USER_TASK_SYSCALL_SATCK_SIZE
;
initParam
->
usTaskPrio
=
OS_TASK_PRIORITY_LOWEST
;
initParam
->
policy
=
LOS_SCHED_RR
;
if
(
processID
==
OS_INVALID_VALUE
)
{
initParam
->
uwStackSize
=
OS_USER_TASK_SYSCALL_SATCK_SIZE
;
//设置任务栈大小,这里用了用户态下系统调用的栈大小(12K)
initParam
->
usTaskPrio
=
OS_TASK_PRIORITY_LOWEST
;
//设置默认优先级
initParam
->
policy
=
LOS_SCHED_RR
;
//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式
if
(
processID
==
OS_INVALID_VALUE
)
{
//外面没指定进程ID的处理
SCHEDULER_LOCK
(
intSave
);
processCB
=
OsCurrProcessGet
();
initParam
->
processID
=
processCB
->
processID
;
initParam
->
consoleID
=
processCB
->
consoleID
;
processCB
=
OsCurrProcessGet
();
//拿当前运行的进程
initParam
->
processID
=
processCB
->
processID
;
//进程ID赋值
initParam
->
consoleID
=
processCB
->
consoleID
;
//任务控制台ID归属
SCHEDULER_UNLOCK
(
intSave
);
}
else
{
processCB
=
OS_PCB_FROM_PID
(
processID
);
if
(
!
(
processCB
->
processStatus
&
(
OS_PROCESS_STATUS_INIT
|
OS_PROCESS_STATUS_RUNNING
)))
{
return
OS_INVALID_VALUE
;
}
else
{
//外面指定了进程ID的处理
processCB
=
OS_PCB_FROM_PID
(
processID
);
//通过ID拿到进程PCB
if
(
!
(
processCB
->
processStatus
&
(
OS_PROCESS_STATUS_INIT
|
OS_PROCESS_STATUS_RUNNING
)))
{
//进程状态有初始和正在运行两个标签时
return
OS_INVALID_VALUE
;
//????? 为什么这两种情况下会无效
}
initParam
->
processID
=
processID
;
initParam
->
consoleID
=
0
;
initParam
->
processID
=
processID
;
//进程ID赋值
initParam
->
consoleID
=
0
;
//默认0号控制台
}
ret
=
LOS_TaskCreateOnly
(
&
taskID
,
initParam
);
ret
=
LOS_TaskCreateOnly
(
&
taskID
,
initParam
);
//只创建task实体,不申请调度
if
(
ret
!=
LOS_OK
)
{
return
OS_INVALID_VALUE
;
}
return
taskID
;
}
//获取任务的调度方式
LITE_OS_SEC_TEXT
INT32
LOS_GetTaskScheduler
(
INT32
taskID
)
{
UINT32
intSave
;
...
...
@@ -1887,45 +1887,45 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
return
-
LOS_EINVAL
;
}
taskCB
=
OS_TCB_FROM_TID
(
taskID
);
taskCB
=
OS_TCB_FROM_TID
(
taskID
);
//通过任务ID获得任务TCB
SCHEDULER_LOCK
(
intSave
);
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_UNUSED
)
{
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_UNUSED
)
{
//状态不能是没有在使用
policy
=
-
LOS_EINVAL
;
OS_GOTO_ERREND
();
}
policy
=
taskCB
->
policy
;
policy
=
taskCB
->
policy
;
//任务的调度方式
LOS_ERREND:
SCHEDULER_UNLOCK
(
intSave
);
return
policy
;
}
//以不安全的方式设置任务的调度信息, 不安全指的是SCHEDULER_LOCK 在两个函数中SCHEDULER_UNLOCK
LITE_OS_SEC_TEXT
INT32
OsTaskSchedulerSetUnsafe
(
LosTaskCB
*
taskCB
,
UINT16
policy
,
UINT16
priority
,
BOOL
policyFlag
,
UINT32
intSave
)
{
BOOL
needSched
=
TRUE
;
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_READY
)
{
OS_TASK_PRI_QUEUE_DEQUEUE
(
OS_PCB_FROM_PID
(
taskCB
->
processID
),
taskCB
);
}
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_READY
)
{
//就绪状态的处理
OS_TASK_PRI_QUEUE_DEQUEUE
(
OS_PCB_FROM_PID
(
taskCB
->
processID
),
taskCB
);
//先出就绪队列,因为这里是要改变优先级的.
}
//一旦任务的调度优先级,将划到对应优先级的队列中,每个进程都有32个任务就绪队列. process.threadPriQueueList负责管理
if
(
policyFlag
==
TRUE
)
{
if
(
policy
==
LOS_SCHED_FIFO
)
{
taskCB
->
timeSlice
=
0
;
if
(
policyFlag
==
TRUE
)
{
//TRUE表示 调度方式要改
if
(
policy
==
LOS_SCHED_FIFO
)
{
//如果是 FIFO 方式
taskCB
->
timeSlice
=
0
;
//不要时间片,只有抢占式才会需要时间片
}
taskCB
->
policy
=
policy
;
taskCB
->
policy
=
policy
;
//改变调度方式
}
taskCB
->
priority
=
priority
;
taskCB
->
priority
=
priority
;
//改变优先级
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_INIT
)
{
taskCB
->
taskStatus
&=
~
OS_TASK_STATUS_INIT
;
taskCB
->
taskStatus
|=
OS_TASK_STATUS_READY
;
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_INIT
)
{
//如果任务状态有初始状态的标签
taskCB
->
taskStatus
&=
~
OS_TASK_STATUS_INIT
;
//去掉初始状态标签
taskCB
->
taskStatus
|=
OS_TASK_STATUS_READY
;
//贴上就绪标签
}
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_READY
)
{
taskCB
->
taskStatus
&=
~
OS_TASK_STATUS_READY
;
OS_TASK_SCHED_QUEUE_ENQUEUE
(
taskCB
,
OS_PROCESS_STATUS_INIT
);
}
else
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_RUNNING
)
{
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_READY
)
{
//如果有就绪标签
taskCB
->
taskStatus
&=
~
OS_TASK_STATUS_READY
;
//去掉就绪标签,why这么做?因为只有非就绪状态的任务才可能加入 OS_TASK_SCHED_QUEUE_ENQUEUE
OS_TASK_SCHED_QUEUE_ENQUEUE
(
taskCB
,
OS_PROCESS_STATUS_INIT
);
//任务加入到调度队列 ,具体看他的函数实现 OsTaskSchedQueueEnqueue
}
else
if
(
taskCB
->
taskStatus
&
OS_TASK_STATUS_RUNNING
)
{
//如果有运行标签,直接goto调度
goto
SCHEDULE
;
}
else
{
needSched
=
FALSE
;
...
...
@@ -1936,12 +1936,12 @@ SCHEDULE:
LOS_MpSchedule
(
OS_MP_CPU_ALL
);
if
(
OS_SCHEDULER_ACTIVE
&&
(
needSched
==
TRUE
))
{
LOS_Schedule
();
LOS_Schedule
();
//申请调度
}
return
LOS_OK
;
}
//设置任务的调度信息
LITE_OS_SEC_TEXT
INT32
LOS_SetTaskScheduler
(
INT32
taskID
,
UINT16
policy
,
UINT16
priority
)
{
UINT32
intSave
;
...
...
@@ -1959,9 +1959,9 @@ LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16
return
LOS_EINVAL
;
}
SCHEDULER_LOCK
(
intSave
);
SCHEDULER_LOCK
(
intSave
);
//拿到自旋锁
taskCB
=
OS_TCB_FROM_TID
(
taskID
);
return
OsTaskSchedulerSetUnsafe
(
taskCB
,
policy
,
priority
,
TRUE
,
intSave
);
return
OsTaskSchedulerSetUnsafe
(
taskCB
,
policy
,
priority
,
TRUE
,
intSave
);
//以不安全的方式设置任务的调度信息,为什么不安全? 因为自旋锁跨了一个函数
}
LITE_OS_SEC_TEXT
VOID
OsWriteResourceEvent
(
UINT32
events
)
...
...
kernel/base/include/los_process_pri.h
浏览文件 @
1b01ca35
...
...
@@ -359,7 +359,7 @@ STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB)
return
(
processCB
->
exitCode
)
&
0x7FU
;
//低7位全部置1
}
STATIC
INLINE
VOID
OsProcessExitCodeSet
(
LosProcessCB
*
processCB
,
UINT32
code
)
//外界提供退出码
STATIC
INLINE
VOID
OsProcessExitCodeSet
(
LosProcessCB
*
processCB
,
UINT32
code
)
//
由
外界提供退出码
{
processCB
->
exitCode
|=
((
code
&
0x000000FFU
)
<<
8U
)
&
0x0000FF00U
;
/* 8: Move 8 bits to the left, exitCode */
}
...
...
kernel/base/include/los_task_pri.h
浏览文件 @
1b01ca35
...
...
@@ -297,7 +297,7 @@ typedef struct {
VOID
*
stackPointer
;
/**< Task stack pointer */
UINT16
taskStatus
;
/**< Task status */
UINT16
priority
;
/**< Task priority */
UINT16
policy
;
UINT16
policy
;
//任务的调度方式(三种 .. LOS_SCHED_RR )
UINT16
timeSlice
;
/**< Remaining time slice */
UINT32
stackSize
;
/**< Task stack size */
UINTPTR
topOfStack
;
/**< Task stack top */
...
...
@@ -318,7 +318,7 @@ typedef struct {
the priority can not be greater than 31 */
INT32
errorNo
;
/**< Error Num */
UINT32
signal
;
/**< Task signal */
sig_cb
sig
;
sig_cb
sig
;
//信号控制块
#if (LOSCFG_KERNEL_SMP == YES)
UINT16
currCpu
;
/**< CPU core number of this task is running on */
UINT16
lastCpu
;
/**< CPU core number of this task is running on last time */
...
...
@@ -334,8 +334,8 @@ typedef struct {
SchedStat
schedStat
;
/**< Schedule statistics */
#endif
#endif
UINTPTR
userArea
;
UINTPTR
userMapBase
;
UINTPTR
userArea
;
//使用区域,由运行时划定,根据运行态不同而不同
UINTPTR
userMapBase
;
//使用区栈底位置
UINT32
userMapSize
;
/**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
UINT32
processID
;
/**< Which belong process */
FutexNode
futex
;
...
...
@@ -345,9 +345,9 @@ typedef struct {
UINT16
waitFlag
;
/**< The type of child process that is waiting, belonging to a group or parent,
a specific child process, or any child process */
#if (LOSCFG_KERNEL_LITEIPC == YES)
UINT32
ipcStatus
;
LOS_DL_LIST
msgListHead
;
BOOL
accessMap
[
LOSCFG_BASE_CORE_TSK_LIMIT
];
UINT32
ipcStatus
;
//IPC状态
LOS_DL_LIST
msgListHead
;
//消息队列头结点
BOOL
accessMap
[
LOSCFG_BASE_CORE_TSK_LIMIT
];
//访问图,指的是task之间是否能访问的标识,LOSCFG_BASE_CORE_TSK_LIMIT 为任务池总数
#endif
}
LosTaskCB
;
...
...
kernel/extended/dynload/src/los_exec_elf.c
浏览文件 @
1b01ca35
...
...
@@ -36,17 +36,17 @@
#include "los_vm_phys.h"
#include "los_vm_map.h"
#include "los_vm_dump.h"
//进程开始执行,参数为加载完ELF后的信息
STATIC
INT32
OsExecve
(
const
ELFLoadInfo
*
loadInfo
)
{
if
((
loadInfo
==
NULL
)
||
(
loadInfo
->
elfEntry
==
0
))
{
if
((
loadInfo
==
NULL
)
||
(
loadInfo
->
elfEntry
==
0
))
{
//参数检查
return
LOS_NOK
;
}
return
OsExecStart
((
TSK_ENTRY_FUNC
)(
loadInfo
->
elfEntry
),
(
UINTPTR
)
loadInfo
->
stackTop
,
loadInfo
->
stackBase
,
loadInfo
->
stackSize
);
loadInfo
->
stackBase
,
loadInfo
->
stackSize
);
//进程开始执行,设置上栈顶,栈底,栈大小
}
//获取真正的路径
#ifdef LOSCFG_SHELL
STATIC
INT32
OsGetRealPath
(
const
CHAR
*
fileName
,
CHAR
*
buf
,
UINT32
maxLen
)
{
...
...
@@ -54,7 +54,7 @@ STATIC INT32 OsGetRealPath(const CHAR *fileName, CHAR *buf, UINT32 maxLen)
UINT32
len
,
workPathLen
,
newLen
;
if
(
access
(
fileName
,
F_OK
)
<
0
)
{
workingDirectory
=
OsShellGetWorkingDirtectory
();
workingDirectory
=
OsShellGetWorkingDirtectory
();
//获取工作目录
if
(
workingDirectory
==
NULL
)
{
goto
ERR_FILE
;
}
...
...
@@ -86,13 +86,13 @@ ERR_FILE:
return
-
ENOENT
;
}
#endif
//拷贝用户参数
STATIC
INT32
OsCopyUserParam
(
ELFLoadInfo
*
loadInfo
,
const
CHAR
*
fileName
,
CHAR
*
kfileName
,
UINT32
maxSize
)
{
UINT32
strLen
;
errno_t
err
;
if
(
LOS_IsUserAddress
((
VADDR_T
)(
UINTPTR
)
fileName
))
{
if
(
LOS_IsUserAddress
((
VADDR_T
)(
UINTPTR
)
fileName
))
{
//在用户空间
err
=
LOS_StrncpyFromUser
(
kfileName
,
fileName
,
PATH_MAX
+
1
);
if
(
err
==
-
EFAULT
)
{
return
err
;
...
...
@@ -100,9 +100,9 @@ STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR *
PRINT_ERR
(
"%s[%d], filename len exceeds maxlen: %d
\n
"
,
__FUNCTION__
,
__LINE__
,
PATH_MAX
);
return
-
ENAMETOOLONG
;
}
}
else
if
(
LOS_IsKernelAddress
((
VADDR_T
)(
UINTPTR
)
fileName
))
{
}
else
if
(
LOS_IsKernelAddress
((
VADDR_T
)(
UINTPTR
)
fileName
))
{
//在内核空间
strLen
=
strlen
(
fileName
);
err
=
memcpy_s
(
kfileName
,
PATH_MAX
,
fileName
,
strLen
);
err
=
memcpy_s
(
kfileName
,
PATH_MAX
,
fileName
,
strLen
);
//从filename -> kfilename
if
(
err
!=
EOK
)
{
PRINT_ERR
(
"%s[%d], Copy failed! err: %d
\n
"
,
__FUNCTION__
,
__LINE__
,
err
);
return
-
EFAULT
;
...
...
@@ -117,7 +117,7 @@ STATIC INT32 OsCopyUserParam(ELFLoadInfo *loadInfo, const CHAR *fileName, CHAR *
INT32
LOS_DoExecveFile
(
const
CHAR
*
fileName
,
CHAR
*
const
*
argv
,
CHAR
*
const
*
envp
)
{
ELFLoadInfo
loadInfo
=
{
0
};
ELFLoadInfo
loadInfo
=
{
0
};
//ELF加载信息结构体
CHAR
kfileName
[
PATH_MAX
+
1
]
=
{
0
};
INT32
ret
;
#ifdef LOSCFG_SHELL
...
...
@@ -130,7 +130,7 @@ INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *e
((
envp
!=
NULL
)
&&
!
LOS_IsUserAddress
((
VADDR_T
)(
UINTPTR
)
envp
)))
{
return
-
EINVAL
;
}
ret
=
OsCopyUserParam
(
&
loadInfo
,
fileName
,
kfileName
,
PATH_MAX
);
ret
=
OsCopyUserParam
(
&
loadInfo
,
fileName
,
kfileName
,
PATH_MAX
);
//将文件名拷贝到内核空间,PATH_MAX = 256
if
(
ret
!=
LOS_OK
)
{
return
ret
;
}
...
...
@@ -144,15 +144,15 @@ INT32 LOS_DoExecveFile(const CHAR *fileName, CHAR * const *argv, CHAR * const *e
}
#endif
loadInfo
.
newSpace
=
LOS_MemAlloc
(
m_aucSysMem0
,
sizeof
(
LosVmSpace
));
loadInfo
.
newSpace
=
LOS_MemAlloc
(
m_aucSysMem0
,
sizeof
(
LosVmSpace
));
//分配一个虚拟空间结构体
if
(
loadInfo
.
newSpace
==
NULL
)
{
PRINT_ERR
(
"%s %d, failed to allocate new vm space
\n
"
,
__FUNCTION__
,
__LINE__
);
return
-
ENOMEM
;
}
virtTtb
=
LOS_PhysPagesAllocContiguous
(
1
);
virtTtb
=
LOS_PhysPagesAllocContiguous
(
1
);
//分配一个物理页用于存放L1页表,虚拟地址<--->物理地址映射使用
if
(
virtTtb
==
NULL
)
{
PRINT_ERR
(
"%s %d, failed to allocate ttb page
\n
"
,
__FUNCTION__
,
__LINE__
);
LOS_MemFree
(
m_aucSysMem0
,
loadInfo
.
newSpace
);
LOS_MemFree
(
m_aucSysMem0
,
loadInfo
.
newSpace
);
//
return
-
ENOMEM
;
}
...
...
syscall/process_syscall.c
浏览文件 @
1b01ca35
...
...
@@ -862,7 +862,7 @@ unsigned int SysCreateUserThread(const TSK_ENTRY_FUNC func, const UserTaskParam
return
OsCreateUserTask
(
OS_INVALID_VALUE
,
&
param
);
}
//系统调用-设置线程使用区域,所有的系统调用都运行在内核态,也运行在内核空间
int
SysSetThreadArea
(
const
char
*
area
)
{
unsigned
int
intSave
;
...
...
@@ -870,27 +870,27 @@ int SysSetThreadArea(const char *area)
LosProcessCB
*
processCB
=
NULL
;
unsigned
int
ret
=
LOS_OK
;
if
(
!
LOS_IsUserAddress
((
unsigned
long
)(
uintptr_t
)
area
))
{
if
(
!
LOS_IsUserAddress
((
unsigned
long
)(
uintptr_t
)
area
))
{
//区域不能在用户空间
return
EINVAL
;
}
SCHEDULER_LOCK
(
intSave
);
taskCB
=
OsCurrTaskGet
();
processCB
=
OS_PCB_FROM_PID
(
taskCB
->
processID
);
if
(
processCB
->
processMode
!=
OS_USER_MODE
)
{
taskCB
=
OsCurrTaskGet
();
//获取当前任务
processCB
=
OS_PCB_FROM_PID
(
taskCB
->
processID
);
//获取当前进程
if
(
processCB
->
processMode
!=
OS_USER_MODE
)
{
//当前进程不能是用户模式
ret
=
EPERM
;
goto
OUT
;
}
taskCB
->
userArea
=
(
unsigned
long
)(
uintptr_t
)
area
;
taskCB
->
userArea
=
(
unsigned
long
)(
uintptr_t
)
area
;
//task的使用区域
OUT:
SCHEDULER_UNLOCK
(
intSave
);
return
ret
;
}
//获取系统调用线程的使用区域
char
*
SysGetThreadArea
(
void
)
{
return
(
char
*
)(
OsCurrTaskGet
()
->
userArea
);
return
(
char
*
)(
OsCurrTaskGet
()
->
userArea
);
//直接返回使用区域
}
int
SysUserThreadSetDeatch
(
unsigned
int
taskID
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录