鸿蒙系统的shell 原创
鸿蒙系统的shell
liangkz 2021.07.14
我的专栏文章中有不少地方都提到了鸿蒙系统的shell,有些地方是当时理解不到位,说错话了~~,本文做一下统一的修正。
小型系统编译内核的入口在B_LTS/kernel/liteos_a/BUILD.gn,打开看一下:
declare_args() {
enable_ohos_kernel_liteos_a_ext_build = true
LOSCFG_TEST_APPS = false
tee_enable = ""
}
lite_subsystem("kernel") {
subsystem_components = []
if (enable_ohos_kernel_liteos_a_ext_build == false) {
.....【略】
} else {
deps = [ ":make" ]
}
}
build_ext_component("make") {
exec_path = rebase_path(".", root_build_dir)
tee_enable = "false"
if (board_name == "hi3516dv300" && enable_tee_ree) {
tee_enable = "tee"
}
prebuilts = "sh build.sh ${board_name} ${ohos_build_compiler} ${root_build_dir} ${ohos_build_type} ${tee_enable} \"${device_company}\" \"${product_path}\""
outdir = rebase_path(get_path_info(".", "out_dir"))
command = "make clean OUTDIR=$outdir && make rootfs VERSION=\"${ohos_version}\" -j 16 OUTDIR=$outdir"
}
所以,kernel子系统的编译,依赖于make这个组件,而make组件则是通过执行同目录下的build.sh做预编译,然后通过make+Makefile来构建编译内核的。
同目录下的.config配置文件,就是预编译时根据各种配置最终生成的编译内核的一组宏定义,相当于对内核又做了一次裁剪。
如,编译release版本时,LOSCFG_SHELL没有定义,内核应用shell是不编译的;当编译debug版本时,LOSCFG_SHELL=y,就会编译shell。
编译内核的中间产物,全都在B_LTS/out/hispark_taurus/ipcamera_hispark_taurus/obj/kernel/liteos_a/目录下,我们暂且将它称为“kernel_out”目录。
查看kernel_out/build.log,可以查看内核的大概编译过程,不过我们暂不深入去分析,这里主要看一下B_LTS/kernel/liteos_a/apps/目录下的三个内核应用shell、init、tftp,以及B_LTS/kernel/liteos_a/shell/目录下的full_shell的编译。
full_shell会编译成静态库到kernel_out/lib/libshell.a,后面会连同其他库文件链接到liteos镜像中。
三个内核应用会编译成同名的可执行程序,生成在kernel_out/bin/目录下,连同kernel_out/musl/目录下的动态库等文件,一起拷贝到B_LTS/out/hispark_taurus/ipcamera_hispark_taurus/rootfs/对应的目录中。
系统启动初期,在SystemInit()函数中,就有对console的初始化相关工作,会调用B_LTS/kernel/liteos_a/shell/ 编译出来的libshell.a提供的函数来完成控制台和内核shell服务的初始化
[system_init] SystemInit[20-18]: system_console_init ...
[console] system_console_init()->OsConsoleCreate()
[console] system_console_init()->OsShellInit() //debug版本才有这个调用,用LOSCFG_SHELL括住的
[shell][full_show] OsShellInit[2-1]->OsShellCmdInit()
[shell][full_show] OsShellInit[2-2]->OsShellSourceInit()
[shell][full_show] OsShellSourceInit()->OsShellKeyInit()
[shell][full_shcmd] OsShellKeyInit()
启动到框架层的系统服务shell时,执行的是内核应用shell程序,入口在B_LTS\kernel\liteos_a\apps\shell\src\main.c,从抓回来的log看,这里跑的是apps的shell的流程,
{Process[03]:shell}
[shell][apps_main] main[2-1]->OsShellKeyInit()
[shell][apps_shcmd] OsShellKeyInit()
[shell][apps_main] main[2-2]->OsShellCreateTask()
[shell][apps_main] OsShellCreateTask[2-1]->ShellTaskInit()
[shell][apps_shmsg] ShellTaskInit()
[shell][apps_main] OsShellCreateTask[2-2]->ShellEntryInit()
[shell][apps_shmsg] ShellEntryInit()
[shell][apps_shmsg] ShellTask() while(1) wait for ShellCmdProcess()
OHOS #
但是,当你在shell下执行命令时,你会发现有部分命令(如date、ping、task等),直接在apps shell内就可以完成,而另外一些命令(如cd、ls等),则需要full shell来提供。这是因为apps shell是一个精简版的shell,只提供基础功能,而full shell是全功能的shell。
如以下命令,只跑apps_shmsg部分,和跑了apps_shmsg之后还要跑full_show,注意两者的差别。
OHOS # date
[shell][apps_shmsg] ShellCmdProcess(date)
[shell][apps_shmsg] ParseAndExecCmdline()->DoCmdExec(date)
Thu Jan 1 00:01:47 1970
OHOS # ping 192.168.1.1
[shell][apps_shmsg] ShellCmdProcess(ping 192.168.1.1)
[shell][apps_shmsg] ParseAndExecCmdline()->DoCmdExec(ping)
[0]Reply from 192.168.1.1: time=4ms TTL=64
[1]Reply from 192.168.1.1: time<1ms TTL=64
OHOS # cd bin
[shell][apps_shmsg] ShellCmdProcess(cd bin)
[shell][apps_shmsg] ParseAndExecCmdline()->DoCmdExec(cd)
[shell][full_show] OsShellGetWorkingDirtectory()
OHOS # ls
[shell][apps_shmsg] ShellCmdProcess(ls)
[shell][apps_shmsg] ParseAndExecCmdline()->DoCmdExec(ls)
[shell][full_show] OsShellGetWorkingDirtectory()
Directory /bin:
-rwxrwxrwx 29920 u:0 g:0 shell
-rwxrwxrwx 25828 u:0 g:0 tftp
-rwxrwxrwx 13488 u:0 g:0 foundation
有深度,感谢分享