鸿蒙系统的shell 原创

发布于 2021-7-14 18:50
浏览
4收藏

鸿蒙系统的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

 

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-7-14 19:25:30修改
6
收藏 4
回复
举报
回复
添加资源
添加资源将有机会获得更多曝光,你也可以直接关联已上传资源 去关联
    相关推荐