Linux 内核 APILinux 内核 APILinux 内核 APILinux 内核 API
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

Linux 内核 API

我们将了解 Linux 应用程序编程接口 API。 Linux内核提供了系统调用,可用于通过内核完成任务。让我们讨论一下 Linux 中少数几个广泛使用的系统调用。

描述:

Linux 内核提供了用户空间程序可以使用的函数集或列表来利用 Linux 内核服务。

框图如下所示:

少数广泛使用的系统调用包括 open、close、read 和 write。这些是Linux内核提供的基本系统调用。 Linux 中的每项任务都是通过文件完成的。因此,对任何文件的基本操作都可以通过打开、关闭、读取和写入来完成。

让我们举一个真实的例子,我们想要在串行控制台上打印“hello world”。为了通过系统调用来完成这个任务,我们需要打开/dev中控制台的设备文件。一旦我们找到控制台或uart的设备文件,我们就可以使用open系统调用来打开设备。

以下是 open 系统调用的语法:

int open(const char *pathname, int flags);

int open(const char *pathname, int flags, mode_t mode);

从这个语法中,第一个参数是我们要打开的文件路径。在我们的例子中,它是我们定位为控制台设备的设备文件。在下一个参数中,标志为用户提供了一些处理文件的灵活性。标志的几个示例是 O_CREAT、O_APPEND 等。这些标志具有特定的含义和目的,讨论超出了本讨论的范围。有关标志和参数的更多详细信息,请参阅内核手册页。

一旦文件成功打开,我们需要使用 write 系统调用将“hello world”发送到控制台设备。 write系统调用的原型如下:

ssize_t write(int fd, const void *buf, size_t count);

write系统调用的第一个参数是fd,它是文件描述符。 “fd”是由 open 系统调用提供给我们的。成功打开文件后,我们应该得到文件描述符。该fd进一步用于写入数据。

第二个参数是要发送到控制台设备的数据的缓冲区地址。在我们的例子中,测试数据是“hello world”。

最后一个参数是用户想要写入控制台设备的字节总数。在我们的例子中,字节数就是“hello world”的大小。我们可以使用 sizeof 运算符或 strlen 函数来获取字节数。我们在使用 strlen 时应该小心。该函数忽略“\0”等字符串终止符。因此,在读取字符串时,我们必须确保空字符得到正确处理。否则,我们最终会出现分段错误。

现在,让我们实现这个例子的代码部分。首先,我们需要找到串行控制台或UART设备。在机器中,我们使用的串行tty设备为/dev/pts/0。因此,正如所讨论的,我们首先需要打开这个文件。我们还必须包含提供开放系统调用声明的较难文件。

我们打开设备文件的代码如下所示:

#include <fcntl.h>

fd = open(“/dev/pts/0”, O_WRONLY);

接下来,当我们要调用write系统调用时,我们使用open提供的fd。我们对 write 函数的调用如下所示:

#include <unistd.h>

char *data = “hello world”;

write(fd, data, strlen(data)+1);

前面的代码片段将“hello world”写入我们找到并想要写入的串行控制台。

让我们把所有的部分放在一起:

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main()
{
    int fd; int rc;
    char *data = “hello world”;
fd = open(“/dev/pts/0”, O_WRONLY);
    if(fd<0)
    {
printf(“Error opening file:%d”,fd);
        exit(-1);
    }
rc = write(fd, data, strlen(data)+1);
    if(rc<0)
    {
printf(“Error writing file:%d”,rc);
        exit(-1);
    }
    close(fd);  // file operation is done, close the file.
    return 0;
}

前一个程序的编译与编译其他 C 程序相同,如下所示:

gcc test_write.c -o test_write.

test_write.c 是我们的 C 代码的文件名。

编译后,我们得到名为 test_write 的可执行文件。

请参考以下快照:

运行编译和生成的二进制文件后,我们有以下输出。

我们的程序输出以粗体字母突出显示。以下是截图供参考:

到目前为止,我们已经看到了一个使用 Linux API 将测试字符串显示到控制台的示例。这是一个简单的例子。系统调用还提供了许多其他功能。 Linux 提供的一些系统调用如下:

  • 读取:从文件中读取。

  • 写入:写入文件。

  • 打开:打开文件。

  • 关闭:关闭文件。

  • 轮询:轮询设备以了解状态变化。

  • lseek:在文件中查找特定偏移量。

  • mmap:将虚拟内存映射到物理内存。

  • brk:更改段大小。

  • ioctl:控制设备。

  • 访问权限:访问权限以获取文件的权限。

  • 管道:指管道创建。

还有很多。

这是 Linux 内核提供的庞大功能列表。我们看到和讨论过的很少。请参阅内核源代码以获取内核提供的系统调用的完整列表。

结论

我们讨论了系统调用,这是一种要求内核为用户空间程序执行任务的方法。如果没有系统调用,用户空间程序将无法完成内核的任务。我们采用了一个简单的任务或示例,将测试数据“hello world”写入串行设备。我们使用内核的 open、write 和 close API 来完成手头的任务。最重要的一件事是检查系统调用返回值。内核提供适当的返回值来解释函数失败的原因。用户可以通过查看系统调用的返回值来了解失败原因。返回值具有一些特定的含义,并且在内核文档中得到了很好的描述。

©2015-2025 艾丽卡 support@alaica.com