编辑
2025-03-30
工作知识
0
请注意,本文编写于 68 天前,最后修改于 68 天前,其中某些信息可能已经过时。

目录

一、设置登录账号
二、shell脚本执行
三、命令执行

为了更清楚的了解rtems的shell功能,这里以两个例子来演示shell功能。

一、设置登录账号

根据login_check中的rtems_shell_login_check函数,可以发现通过getpwnam_r获取passwd,这里实际调用是getpw_r,如下:

static int getpw_r( const char *name, int uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result ) { FILE *fp; int match; _libcsupport_pwdgrp_init(); if ((fp = fopen("/etc/passwd", "r")) == NULL) rtems_set_errno_and_return_minus_one( EINVAL ); for(;;) { if (!_libcsupport_scanpw(fp, pwd, buffer, bufsize)) goto error_einval; if (name) { match = (strcmp(pwd->pw_name, name) == 0); } else { match = (pwd->pw_uid == uid); } if (match) { fclose(fp); *result = pwd; return 0; } } error_einval: fclose(fp); rtems_set_errno_and_return_minus_one( EINVAL ); }

所以我们知道rtems的账号信息在passwd文件,我们可以在Init中发现其创建了此文件

writeFile( "/etc/passwd", 0644, "root:$6$$FuPOhnllx6lhW2qqlnmWvZQLJ8Thr/09I7ESTdb9VbnTOn5.65" "/Vh2Mqa6FoKXwT0nHS/O7F0KfrDc6Svb/sH.:0:0:root::/:/bin/sh\n" "rtems::1:1:RTEMS Application::/:/bin/sh\n" "test:$1$$oPu1Xt2Pw0ngIc7LyDHqu1:2:2:test account::/:/bin/sh\n" "tty:*:3:3:tty owner::/:/bin/false\n" "chroot::4:2:chroot account::/chroot:/bin/sh\n" );

这里可以发现,如果我们新增一个用户,则在这里写入信息即可。需要注意的是密码被加密了。我们需要留意加密方式代码如下

crypt_add_format(&crypt_md5_format); crypt_add_format(&crypt_sha512_format); struct crypt_format crypt_md5_format = CRYPT_FORMAT_INITIALIZER(crypt_md5_r, "$1$"); struct crypt_format crypt_sha512_format = CRYPT_FORMAT_INITIALIZER(crypt_sha512_r, "$6$");

也就是我们可以通过md5和sha512两种方式加密

通过python3我们可以测试如下,假设我们设置密码是kylinos,则

>>> print(crypt.crypt("kylinos", "$1$")) $1$$PZwUkYqm0zRLtkgaIFzoq/ >>> print(crypt.crypt("kylinos", "$6$")) $6$$FXse0c1.Rfb8DWjwHmjUZNzufS4shiUUIVwzonK6LcfAlEWAYXPyxwfZhjV0C5.7tlU/ZUgh5e8GI2MPo7W02.

所以我们可以为rtems设置两个账户,一个是rtems,使用md5加密,一个是kylin,使用sha512加密

diff --git a/testsuites/samples/fileio/init.c b/testsuites/samples/fileio/init.c index 084d54d81a..a8e95874ef 100644 --- a/testsuites/samples/fileio/init.c +++ b/testsuites/samples/fileio/init.c @@ -584,10 +584,11 @@ static void fileio_start_shell(void) 0644, "root:$6$$FuPOhnllx6lhW2qqlnmWvZQLJ8Thr/09I7ESTdb9VbnTOn5.65" "/Vh2Mqa6FoKXwT0nHS/O7F0KfrDc6Svb/sH.:0:0:root::/:/bin/sh\n" - "rtems::1:1:RTEMS Application::/:/bin/sh\n" + "rtems:$1$$PZwUkYqm0zRLtkgaIFzoq/:1:1:RTEMS Application::/:/bin/sh\n" "test:$1$$oPu1Xt2Pw0ngIc7LyDHqu1:2:2:test account::/:/bin/sh\n" "tty:*:3:3:tty owner::/:/bin/false\n" "chroot::4:2:chroot account::/chroot:/bin/sh\n" + "kylin:$6$$FXse0c1.Rfb8DWjwHmjUZNzufS4shiUUIVwzonK6LcfAlEWAYXPyxwfZhjV0C5.7tlU/ZUgh5e8GI2MPo7W02.:5:5:KylinOS User::/:/bin/sh\n" );

构建验证即可。可以确认kylin 和 rtems两个账户的密码 kylinos都能登录。

二、shell脚本执行

为了使得rtems支持shell脚本执行,我们需要按照joel的方式编写脚本。我们可以在Init中通过writeScript和rtems_shell_write_file写入shell文件,如下

+ writeScript( + "/kylin", + "#! joel\n" + "echo Hello KylinOS\n" + ); + + rtems_shell_write_file( + "/kylin1", + "#! joel\n" + "echo Hello KylinOS\n" + );

编译后,运行如下:

SHLL [/] # ./kylin Hello KylinOS SHLL [/] # ./kylin1 Unable to execute //kylin1

可以发现rtems_shell_write_file的文件,及时内容正确,但是无法运行,我们需要为其添加权限,如下

SHLL [/] # chmod 0777 /kylin1 SHLL [/] # ./kylin1 Hello KylinOS

三、命令执行

为了内置rtems的命令,可以通过自己实现命令的方式,主要如下:

首先我们添加一个c文件,用作kylin命令,路径为cpukit/libmisc/shell/main_kylin.c内容为:

static int rtems_shell_main_kylin(int argc, char *argv[]) { printf("Kylin Say: Hello World!\n"); return 0; } rtems_shell_cmd_t rtems_shell_KYLIN_Command = { "kylin", /* name */ "kylin # show message", /* usage */ "system1", /* topic */ rtems_shell_main_kylin , /* command */ NULL, /* alias */ NULL /* next */ };

然后我们为其增加到cmd初始化的数组中,改动如下:

diff --git a/cpukit/include/rtems/shellconfig.h b/cpukit/include/rtems/shellconfig.h index 489f281400..2b51967f7b 100644 --- a/cpukit/include/rtems/shellconfig.h +++ b/cpukit/include/rtems/shellconfig.h @@ -95,6 +95,7 @@ extern rtems_shell_cmd_t rtems_shell_HEXDUMP_Command; extern rtems_shell_cmd_t rtems_shell_DEBUGRFS_Command; extern rtems_shell_cmd_t rtems_shell_DF_Command; extern rtems_shell_cmd_t rtems_shell_MD5_Command; +extern rtems_shell_cmd_t rtems_shell_KYLIN_Command; extern rtems_shell_cmd_t rtems_shell_RTC_Command; extern rtems_shell_cmd_t rtems_shell_SPI_Command; @@ -606,6 +607,7 @@ extern rtems_shell_alias_t * const rtems_shell_Initial_aliases[]; #if defined(CONFIGURE_SHELL_USER_COMMANDS) CONFIGURE_SHELL_USER_COMMANDS, #endif + &rtems_shell_KYLIN_Command, NULL };

最后我们添加kylin命令的编译,如下

diff --git a/spec/build/cpukit/objshell.yml b/spec/build/cpukit/objshell.yml index 2eaf4e17cf..09fdbaab8a 100644 --- a/spec/build/cpukit/objshell.yml +++ b/spec/build/cpukit/objshell.yml @@ -38,6 +38,7 @@ source: - cpukit/libmisc/shell/main_chdir.c - cpukit/libmisc/shell/main_chmod.c - cpukit/libmisc/shell/main_chroot.c +- cpukit/libmisc/shell/main_kylin.c - cpukit/libmisc/shell/main_cmdchmod.c - cpukit/libmisc/shell/main_cmdchown.c - cpukit/libmisc/shell/main_cmdls.c

编译运行后,我们可以直接调用kylin命令如下:

SHLL [/] # kylin Kylin Say: Hello World!