简单网络驱动(基于 Linux-4.15.x 版本内核)

Doreality 2022-01-19 20:12:27

设计并实现一个简单的网络设备驱动程序(基于 Linux-4.15.x 版本内核)
—— A Simpler Network Device Driver(下文简称 sndd

  • 源码地址(仅供学习交流):https://gitee.com/doreality/sndd
  • 环境:Ubuntu 18.04(Linux-4.15.0 内核)
  • 参考《Linux 设备驱动程序(第3版)》(以下简称“LDD3”)第 17 章“网络驱动程序”的snull模块实现
  • P.S. 下文所提到的“网络设备驱动程序”、“网络设备驱动”、“网络驱动程序”、“网络驱动”都指的是同一个概念。

前言

几个概念理解

  1. 为什么要选择 Linux?

在源码公开和支持模块化这样优点的加成下,Linux 系统非常适合作为学习编写设备驱动程序的环境。

  1. 什么是设备驱动程序?

设备驱动程序,是应用程序和除了CPU、内存等硬件设备之外的几乎所有外设打交道的桥梁。应用程序使用OS提供的统一接口——系统调用,就像使用了一把万能钥匙,可以打开并访问各种不同外设,而并不用关心这些设备本身的样子。

例如块设备,应用程序说打开它,然后读写一些数据,那么直接使用openreadwrite这些系统调用就好了,并不需要考虑数据是怎么在光盘或者磁盘上使用什么不同的介质存储、被组织排列成什么顺序。

  1. 有哪些设备驱动程序?

正因为有越来越多不同的设备出现,设备驱动也是种类繁杂,一般可以分为三类:字符设备驱动、块设备驱动和网络设备驱动。这样分类有利于模块化编程,但是,当然,对于复杂的设备,也可以把这些都综合为一个模块(以灵活性为代价)。

对于字符设备驱动和块设备驱动来说,Linux 系统都会在/dev目录下创建一个文件节点,把它们都抽象为一个文件,可以打开关闭、可以读写也可以进行配置。

  1. 但是网络设备驱动有所不同。

网络设备是要和外界互联的,网络驱动程序要异步地接收来自外界的数据包,然后向内核请求,把这些数据包发送给内核。这和块设备只响应内核的要求、只向固定缓冲区发送数据,是完全不同的。网络驱动没有必要留一个/dev下的节点,因为对它打开关闭也好、读写也罢,并没有实质的意义。网络驱动要做的就是,在收到数据包的时候,发送给内核;在内核要发送数据包的时候,它进行封装(自己的硬件头部)然后发送。

网络驱动在哪里

如果说网络驱动是一把万能钥匙,那也是开大门的钥匙吧,那就是在内核了。这是在应用程序和驱动程序的角度来看。

如果说从网络的分层来看,网络驱动程序就是很底层了。LDD3 中提到,Linux 的网络子系统被设计为和协议完全无关。协议隐藏在驱动程序之后,而物理传输又被隐藏在协议之后。内核和网络驱动之间的交互,可能每次处理的是一个网络数据包。

但是同样值得指出的是,驱动接收的是外界发送的数据包,但是传输时要给上层传递下来的数据包封装一个 MAC 的头部信息。所以驱动会使用硬件协议,但是处理传输的是 IP 数据包。

img

sndd 设计

sndd 实现一个基于内存的网络驱动模块,模拟了网络接口和远程主机通信的过程。

sndd 中使用的接口不依赖于任何硬件,是纯软件实现的数据包传输和发送。

在二层协议上选择以太网协议,处理传输的是 IP 数据包(对其他非 IP 数据包的修改会破坏原本数据包)。

由于使用以太网协议,在实际测试的时候可以使用 tcpdump 工具进行抓包验证数据包的传输。

网络拓扑

驱动模拟了四个网络接口,接口名:sndd0sndd1sndd2sndd3

对应的主机名为 lc0lc1lc2lc3

三个接口位于三个不同的子网,网络名分别为 snet0snet1snet2snet3

在三个网段中,各自分别有一台主机,主机名:rm0rm1rm2rm3

网络结构如下图所示:

img

驱动要实现的功能如下,两个扩展的回环网络:

  • 从主机发送到 rm0 的数据包,要从 sn1 接收到
  • 从主机发送到 rm1 的数据包,要从 sn0 接收到
  • 从主机发送到 rm2 的数据包,要从 sn3 接收到
  • 从主机发送到 rm3 的数据包,要从 sn2 接收到

为了实现上述功能,给各接口和主机分配 IP 地址如下:

# 网络号 /etc/networks
snet0 192.168.4.0
snet1 192.168.5.0
snet2 192.168.6.0
snet3 192.168.7.0

# 主机号 /etc/hosts
192.168.4.1 lc0  
192.168.4.2 rm0
192.168.5.2 lc1
192.168.5.1 rm1
192.168.6.1 lc2
192.168.6.2 rm2
192.168.7.2 lc3
192.168.7.1 rm3

同时,在终端里配置网络接口:

$ sudo ifconfig sndd0 lc0 netmask 255.255.255.0
$ sudo ifconfig sndd1 lc1 netmask 255.255.255.0
$ sudo ifconfig sndd2 lc2 netmask 255.255.255.0
$ sudo ifconfig sndd3 lc3 netmask 255.255.255.0

根据所设置的 IP 地址,为了实现功能,要在驱动中接收到数据包时,修改 IP 数据包的头部中的源 IP 地址和目的 IP 地址:

  • 把第 3 个 octet 依次修改(4->5,5->4,6->7,7->6)
  • 把第 4 个 octet 修改(1->2,2->1)

模块结构

实现一个简单的模块,至少需要包含如下几个部分:

  1. 模块注册和注销
  2. 模块初始化
  3. 模块的具体操作

对于要实现的简单网络设备驱动,

包含的数据结构:

  1. 接口数据结构 struct net_device *
  2. 操作数据结构
    • struct header_ops
    • struct net_device_ops
  3. 自定义数据包 struct sndd_packet
  4. 接口的私有信息 struct sndd_priv

包含操作:

  1. 注册 sndd_init_module()
  2. 注销 sndd_cleanup()
  3. 初始化 sndd_init()
  4. 打开 sndd_open()
  5. 关闭 sndd_release()
  6. 传输 / 接收
    • 传输 sndd_tx()
    • 接收 sndd_rx()
  7. 数据处理
    • 修改 header sndd_header()
    • 单个缓冲区
      • sndd_get_tx_buffer()
      • sndd_release_buffer()
    • 缓冲池
      • 建立:sndd_setup_pool()
      • 回收:sndd_teardown_pool()
    • 缓冲队列
      • sndd_enqueue_buf()
      • sndd_dequeue_buf()
  8. 中断 sndd_regular_interrupt()
  9. 统计 net_device_stats *sndd_stats()
  10. I / O 控制 sndd_ioctl()

使用一些简化:

  • 传输和接收采用中断机制,而不是轮询(NAPI)
  • 不设置传输超时判断
  • 硬件地址由软件模拟
  • 不使用 ARP,采用软件模拟
  • 不修改 MTU

sndd 实现

  1. 模块的注册、注销和初始化

首先是每个模块的注册和注销函数:

module_init(sndd_init_module);
module_exit(sndd_cleanup);

注册,完成的功能就是给每个接口申请内存(在这个步骤里要进行接口的初始化 sndd_init),最关键的就是使用注册函数register_netdev(sndd_devs[i]),把接口注册到内核中。

/*
 * Register the module
 */
int sndd_init_module(void)
{
    int result, i, ret = -ENOMEM;

    sndd_interrupt = sndd_regular_interrupt;

    /* Allocate the devices */
    sndd_devs[0] = alloc_netdev(sizeof(struct sndd_priv), "sndd%d",
            NET_NAME_UNKNOWN, sndd_init);
    sndd_devs[1] = alloc_netdev(sizeof(struct sndd_priv), "sndd%d",
            NET_NAME_UNKNOWN, sndd_init);
    sndd_devs[2] = alloc_netdev(sizeof(struct sndd_priv), "sndd%d",
            NET_NAME_UNKNOWN, sndd_init);
    sndd_devs[3] = alloc_netdev(sizeof(struct sndd_priv), "sndd%d",
            NET_NAME_UNKNOWN, sndd_init);

    if (sndd_devs[0] == NULL || sndd_devs[1] == NULL)
        goto out;

    ret = -ENODEV;
    for (i = 0; i < 4;  i++)
        if ((result = register_netdev(sndd_devs[i])))
            printk("sndd: error %i registering device \"%s\"\n",
                    result, sndd_devs[i]->name);
        else
            ret = 0;
   out:
    if (ret) 
        sndd_cleanup();
    return ret;
}

注销,就是注册的倒序,先从内核中注销,然后清除内部的数据结构,最后释放接口。

/*
 * Unregister the module
 */
void sndd_cleanup(void)
{
    int i;
    
    for (i = 0; i < 4;  i++) {
        if (sndd_devs[i]) {
            unregister_netdev(sndd_devs[i]);
            sndd_teardown_pool(sndd_devs[i]);
            free_netdev(sndd_devs[i]); 
        }
    }
    return;
}

初始化:

/*
 * The init function (sometimes called probe).
 * It is invoked by register_netdev()
 */
void sndd_init(struct net_device *dev)
{
    struct sndd_priv *priv;
    /* 
     * Then, assign other fields in dev, using ether_setup() and some
     * hand assignments
     */
    ether_setup(dev); /* assign some of the fields */
    dev->netdev_ops = &sndd_netdev_ops;
    dev->header_ops = &sndd_header_ops;
    /* keep the default flags, just add NOARP */
    dev->flags           |= IFF_NOARP;
    dev->features        |= NETIF_F_HW_CSUM;

    /*
     * Then, initialize the priv field. This encloses the statistics
     * and a few private fields.
     */
    priv = netdev_priv(dev);
    memset(priv, 0, sizeof(struct sndd_priv));

    spin_lock_init(&priv->lock);
    priv->dev = dev;

    sndd_rx_ints(dev, 1);        /* enable receive interrupts */
    sndd_setup_pool(dev);
}
  1. 数据包的传输

从上层接收到的数据包,要先封装硬件协议(这里是以太网协议)的头部,然后放入发送队列。

每一个数据包都包含在一个 sk_buff 结构中,就是一个 socket 缓冲区。

最后调用 sndd_hw_tx 实现网络驱动的具体操作,就是修改源和目的,实现一个回环功能。

/*
 * Transmit a packet (called by the kernel)
 */
int sndd_tx(struct sk_buff *skb, struct net_device *dev)
{
    int len;
    char *data, shortpkt[ETH_ZLEN];
    struct sndd_priv *priv = netdev_priv(dev);

    data = skb->data;
    len = skb->len;
    if (len < ETH_ZLEN) {
        memset(shortpkt, 0, ETH_ZLEN);
        memcpy(shortpkt, skb->data, skb->len);
        len = ETH_ZLEN;
        data = shortpkt;
    }
    netif_trans_update(dev);

    /* Remember the skb, so we can free it at interrupt time */
    priv->skb = skb;

    /* actual deliver of data is device-specific, and not shown here */
    sndd_hw_tx(data, len, dev);

    return 0; /* Our simple device can not fail */
}
  1. 数据包的接收

由于是使用中断驱动,当数据包异步到达的时候,中断程序调用 sndd_rx 将数据包和附加信息发送到上层。

/*
 * Receive a packet: retrieve, encapsulate and pass over to upper levels
 */
void sndd_rx(struct net_device *dev, struct sndd_packet *pkt)
{
    struct sk_buff *skb;
    struct sndd_priv *priv = netdev_priv(dev);

    /*
     * The packet has been retrieved from the transmission
     * medium. Build an skb around it, so upper layers can handle it
     */
    skb = dev_alloc_skb(pkt->datalen + 2);
    if (!skb) {
        if (printk_ratelimit())
            printk(KERN_NOTICE "sndd rx: low on mem - packet dropped\n");
        priv->stats.rx_dropped++;
        goto out;
    }
    skb_reserve(skb, 2); /* align IP on 16B boundary */  
    memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen);

    /* Write metadata, and then pass to the receive level */
    skb->dev = dev;
    skb->protocol = eth_type_trans(skb, dev);
    skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */
    priv->stats.rx_packets++;
    priv->stats.rx_bytes += pkt->datalen;
    netif_rx(skb);
  out:
    return;
}

更多具体的实现可见源代码并参考 LDD3 中的 snull 模块。

sndd 测试

利用 Makefile 生产 .ko 加载到内核之后,使用 ping 和 tcpdump 可以测试本驱动。

Makefile

和 LDD3 中所给示例基本是一样的。

# Comment/uncomment the following line to disable/enable debugging
#DEBUG = y

# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
  DEBFLAGS = -O -g -DSNULL_DEBUG # "-O" is needed to expand inlines
else
  DEBFLAGS = -O2
endif

EXTRA_CFLAGS += $(DEBFLAGS)
EXTRA_CFLAGS += -I..

ifneq ($(KERNELRELEASE),)
# call from kernel build system
obj-m    := sndd.o
else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif


clean:
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.mod modules.order *.symvers

depend .depend dep:
    $(CC) $(EXTRA_CFLAGS) -M *.c > .depend


ifeq (.depend,$(wildcard .depend))
include .depend
endif

模块测试

  1. 编译并装载模块
$ make
$ sudo insmod sndd.ko

img

模块加载到内核之后,模拟的网络接口就出现了,使用 ifconfig 命令可以查看:

img

  1. 配置网络

如前所述,配置网络和主机号,同时绑定接口的 IP。

img

img

img

  1. 测试

测试效果如下图。

img

当发出ping -c1 1 rm0命令,发送目的地址为 rm0 的数据包请求时,按顺序发送了如下事件:

  • sndd0 上观察到,从 lc0 > rm0 发起了一次请求;
  • sndd1 上观察到,从 rm1 > lc1 发起了一次请求;
  • sndd1 上观察到,从 lc1 > rm1 发起了一次回应;
  • sndd0 上观察到,从 rm0 > lc0 发起了一次回应。

这个过程就实现了一个扩展的回环网络,从 lc0lc1,然后从 lc1 再到 lc0,实现了一次双向的通信。

同理,使用 ping 访问 rm1rm2rm3 时,也实现了这样的过程。

小结

  1. 模块化编程要注意,卸载模块的时候,一定要把申请的所有内存都释放,否则会影响内核下一次启动;
  2. 网络驱动比起字符驱动和块设备驱动,会更抽象一点,实际的使用需要结合具体的网络设备来编写;
  3. 配置测试接口的 IP 时,要多测试一下,如果突然不好用了重新使用 ifconfig 配置一下;
  4. 在实际网络中使用的时候,必须要有传输超时和并发控制(这里没有给出,但是 LDD3 中都有涉及);
  5. 除了中断的方式处理数据接收和发送,还可以使用轮询(NAPI)的方式,常用于流量非常大的高速接口(如宽带接口);
  6. 网络驱动其实并不关注协议内容,但是,需要比较了解协议的结构,才能在需要时很好地处理。

参考

作者:NP 244

...全文
448 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
文件格式为azw3,文字版本,可以用kindle阅读,PC端可以用calibre,可以转成epub所有手机阅读软件都支持,对手机的排版支持还不错. 内容目录 第1天 文本操作指令 1.1 ar 指令:创建、修改或从档案文件中提取文件 1.2 aspell指令:检查文件的错误 1.3 bunzip2指令:解压缩.bz2类型的文件 1.4 bye指令:中断FTP连接 1.5 bzip2指令:压缩成.bz2类型的文件 1.6 bzip2recover指令:损坏.bz2文件的修复 1.7 cat指令:连接并输出文件内容 1.8 chattr指令:改变文件的属性 1.9 chgrp 指令:改变文件或者目录所属的用户组 1.10 chmod指令:改变文件或者目录的权限 1.11 chown指令:改变文件的拥有者或用户组 1.12 cksum指令:文件的CRC校验 1.13 cmp指令:比较文件差异 1.14 cp指令:复制 1.15 cpio指令:备份文件 1.16 csplit指令:分割文件 1.17 cut指令:剪切文件 1.18 diff指令:生成差异信息 1.19 diffstat指令:diff结果的统计信息 1.20 dump指令:文件系统备份 1.21 file指令:辨识文件类型 1.22 find指令:查找目录或者文件 1.23 fsck指令:检查并尝试修改文件系统错误 1.24 fsck.ext2指令:检查ext2文件系统并尝试修改错误 1.25 fsck.ext3指令:检查ext3文件系统并尝试修改错误 1.26 fsck.minix指令:检查文件系统并尝试修复错误 1.27 ftp指令:文件传输协议 1.28 ftpcount指令:显示ftp登录用户数 1.29 ftpshut指令:定时关闭ftp服务器 1.30 ftpwho指令:显示登录ftp用户信息 1.31 gunzip指令:解压缩文件 1.32 gzexe指令:压缩可执行文件 1.33 gzip指令:压缩文件 1.34 indent指令:调整C原始代码文件的格式 1.35 less指令:一次显示一页文本 1.36 lha指令:压缩或解压缩文件 1.37 ln指令:链接文件或目录 1.38 locate指令:查找文件 1.39 lpd指令:打印管理程序 1.40 lpq 指令:查看打印机列表中未完成的工作 1.41 lpr指令:输入打印文件 1.42 lprm 指令:将任务从打印机队列中移除 1.43 lsattr指令:显示文件属性 1.44 mattrib指令:变更或显示MS-DOS文件的属性 1.45 mc指令:菜单式文件管理程序 1.46 mcopy指令:复制MS-DOS文件 1.47 mdel指令:删除MS-DOS文件 1.48 mdir指令:显示MS-DOS目录 1.49 mkdir指令:建立目录 1.50 mktemp指令:建立暂存文件 1.51 more指令:显示文件信息 1.52 mmove指令:移动或重命名MS-DOS文件 1.53 mread指令:复制MS-DOS文件 1.54 mren指令:移动或重命名MS-DOS文件 1.55 mshowfat指令:显示MS-DOS文件的记录 1.56 mtools 指令:显示 mtools 支持的指令 1.57 mtoolstest 指令:测试同时显示mtools的相关设置 1.58 mv 指令:移动或更名现有的文件或目录 1.59 ncftp指令:文件传输 1.60 ncftpget指令:下载文件 1.61 ncftpput指令:上传文件 1.62 od指令:输出文件内容 1.63 paste指令:合并文件的列 1.64 patch指令:修补文件 1.65 rcp指令:远程复制文件或目录 1.66 rhmask指令:产生加密文件 1.67 rm指令:删除文件或目录 1.68 tac指令:反序输出文件 1.69 tar指令:打包同时压缩/解压缩文件 1.70 tee 指令:从标准输入读取数据到标准输出,同时保存为文件 1.71 tftp指令:传输文件 1.72 tmpwatch指令:删除临时文件 1.73 touch指令:更改文件/目录时间 1.74 umask指令:指定在建立文件时权限掩码 1.75 umount指令:卸除文件系统 1.76 unarj指令:解压缩文件 1.77 uncompress指令:解压缩.z文件 1.78 unzip指令:解压缩.zip文件 1.79 uucico指令:.uucp文件传输 1.80 uucp指令:在系统之间传送文件 1.81 uupick指令:处理接收文件 1.82 uuto指令:文件传送到远端主机 1.83 whereis指令:查找文件 1.84 which指令:查找文件 1.85 zip指令:压缩文件 1.86 zipinfo指令:显示压缩文件的信息 第2天 文本编辑指令 2.1 col指令:过滤控制字符 2.2 colrm指令:删除指定的列 2.3 comm指令:比较排序文件 2.4 ed指令:文本编辑器 2.5 egrep指令:输出匹配某种模式的行 2.6 emacs指令:文本编辑器 2.7 ex指令:在Ex模式下启动vim文本编辑器 2.8 expr指令:简单计算器 2.9 fgrep指令:匹配字符串 2.10 fmt指令:编排文本文件 2.11 fold指令:限制文件列宽 2.12 grep指令:匹配搜索 2.13 ispell指令:拼字检查程序 2.14 jed指令:编辑文本文件 2.15 joe指令:编辑文本文件 2.16 join指令:连接两个指定的文件 2.17 look指令:单字查询 2.18 mtype指令:显示MS-DOS文件的内容 2.19 pico指令:编辑文本文件 2.20 rgrep指令:递归查找 2.21 sed指令:利用script命令处理文本文件 2.22 sort指令:将文本文件内容加以排序 2.23 spell指令:拼字检查程序 2.24 tr指令:转换文件中的字符 2.25 uniq指令:检查文件中重复出现的行 2.26 vi指令:文字编辑器 2.27 vim指令:增强型vi文件编辑器 2.28 wc指令:计算字数 第3天 磁盘操作指令 3.1 automount指令:为auto文件系统配置挂载点 3.2 badblocks指令:检查磁盘坏道 3.3 cd指令:切换目录 3.4 cfdisk指令:磁盘分区 3.5 dd指令:转换复制文件 3.6 df指令:磁盘信息 3.7 dirs指令:显示目录信息 3.8 du指令:显示目录或文件所占的磁盘空间 3.9 edquota 指令:编辑用户或用户组的quota 3.10 eject指令:退出抽取式设备 3.11 e2fsck指令:检查ext2文件系统 3.12 fdformat指令:软盘格式化 3.13 fdisk指令:Linux磁盘分区 3.14 fsck 指令:检查文件系统并修复分区错误 3.15 fsck.ext2指令:检查ext2文件系统 3.16 fsconf指令:设置文件系统相关功能 3.17 hdparm指令:显示和设定硬盘参数 3.18 lndir指令:连接目录内容 3.19 losetup指令:设置循环设备 3.20 ls指令:列出目录内容 3.21 mbadblocks 指令:检查 MS-DOS文件系统的磁盘是否有损坏的磁区 3.22 mcd指令:在MS-DOS文件系统中切换工作目录 3.23 mdeltree指令:删除MS-DOS 目录/文件 3.24 mdu指令:显示MS-DOS目录所占用的磁盘空间 3.25 mformat指令:对MS-DOS文件系统的磁盘进行格式化 3.26 mkbootdisk指令:建立目前系统的启动盘 3.27 mkdir指令:建立目录 3.28 mkdosfs指令:建立MS-DOS文件系统 3.29 mke2fs指令:建立ext2文件系统 3.30 mkfs指令:建立各种文件系统 3.31 mkfs.ext2指令:建立ext2文件系统 3.32 mkfs.msdos 指令:建立 MS-DOS文件系统 3.33 mkinitrd指令:建立要载入ramdisk的映像文件 3.34 mkisofts指令:建立iso 9660映像文件 3.35 mkswap指令:设置交换区 3.36 mlabel 指令:显示/设置 MS-DOS磁盘驱动器的标签名称 3.37 mmd 指令:在MS-DOS 文件系统中建立目录 3.38 mmount指令:挂载MS-DOS文件系统 3.39 mount指令:挂载文件系统 3.40 mpartition指令:建立/删除MS-DOS的分区 3.41 mrd指令:删除MS-DOS文件系统中的目录 3.42 pwd指令:显示工作目录 3.43 quota指令:显示磁盘已使用的空间与限制 3.44 quotacheck 指令:检查磁盘的使用空间与限制 3.45 quotaoff指令:关闭磁盘空间限制 3.46 quotaon指令:开启磁盘空间限制 3.47 repquota指令:检查磁盘空间限制的状态 3.48 restore指令:还原dump操作备份文件 3.49 rmdir指令:删除目录 3.50 sfdisk指令:硬盘分区工具程序 3.51 stat指令:显示inode内容 3.52 swapoff指令:关闭系统交换分区 3.53 swapon指令:启动系统交换分区 3.54 symlinks指令:维护符号链接的工具程序 3.55 symlinks 指令:维护符号链接的工具程序 3.56 tree指令:以树状图显示目录内容 3.57 umount指令:卸除文件系统 第4天 网络通信指令 4.1 apachectl指令:apache HTTP服务器控制接口 4.2 arp指令:地址转换协议 4.3 arping指令:ARP请求报文 4.4 arpwatch指令:监听ARP记录 4.5 arptables指令:管理系统的ARP表 4.6 cu指令:主机间通信 4.7 dip指令:IP拨号连接 4.8 dnsconf指令:设置DNS服务器组态 4.9 efax指令:收发传真 4.10 getty指令:设置终端配置 4.11 httpd指令:apache http服务器程序 4.12 ifconfig指令:显示或者配置网络设备 4.13 mesg指令:控制终端的写入 4.14 minicom指令:调制解调器通信程序 4.15 nc指令:设置路由器 4.16 netstat指令:显示网络状态 4.17 newaliases指令:重建别名数据库 4.18 pine指令:处理电子邮件和新闻组 4.19 ping指令:检测主机 4.20 ppp-off指令:关闭ppp连线 4.21 pppsetup指令:设置ppp连线 4.22 pppstats指令:显示ppp连线状态 4.23 samba指令:控制Samba服务端 4.24 sendmail指令:邮件服务器程序 4.25 setserial指令:设置或显示串口的相关信息 4.26 smbclient指令:可存取SMB/CIFS服务器的用户端程序 4.27 smbd指令:Samba服务端 4.28 ssh指令:加密的远程登录工具 4.29 statserial指令:samba服务器程序 4.30 talk指令:与其他用户交谈 4.31 tcpdump指令:倾倒网络传输数据 4.32 telnet指令:远程登录 4.33 testparm 指令:测试 Samba 配置文件 4.34 traceroute指令:显示数据包到主机间的路径 4.35 tty指令:显示标准输入设备名称 4.36 uucp 指令:将特定文件复制到另一个特定系统 4.37 uulog指令:显示uucp记录信息 4.38 uuname指令:显示uucp远端主机 4.39 uustat指令:显示uucp状态 4.40 uux指令:在远端的uucp主机上运行指令 4.41 wall指令:发送信息 4.42 write指令:传送信息 4.43 ytalk指令:与其他用户交谈 第5天 系统管理指令 5.1 adduser指令:增加一个系统用户 5.2 arch指令:输出主机的体系结构 5.3 batch指令:执行批处理指令 5.4 bg指令:将程序放在后台执行 5.5 chfn指令:设置finger信息 5.6 chsh指令:改变登录系统时的shell 5.7 clear指令:清除屏幕信息 5.8 date指令:显示或设置系统时间 5.9 echo指令:字符串输出 5.10 exit指令:退出shell 5.11 finger指令:查找并显示用户信息 5.12 free指令:显示内存信息 5.13 fwhois指令:显示用户的信息 5.14 gitps指令:显示程序情况 5.15 groupadd指令:创建一个新群组 5.16 groupdel指令:删除一个群组 5.17 groupmod 指令:改变系统群组的属性 5.18 groups指令:查看用户属于哪个组 5.19 halt指令:关闭系统 5.20 help指令:显示shell内建指令的帮助信息 5.21 history指令:显示历史指令 5.22 id 指令:显示用户的ID 以及所属群组的ID 5.23 init指令:开关机设置 5.24 ipcs指令:显示进程间通信的信息 5.25 jobs指令:显示所有后台程序 5.26 kill指令:杀死执行中的进程 5.27 last指令:显示所有登录系统的用户相关信息 5.28 lastb 指令:显示登录系统失败的用户信息 5.29 login指令:登录系统 5.30 logname指令:显示登录账号 5.31 logout指令:退出系统 5.32 logrotate指令:管理log文件 5.33 man指令:帮助手册 5.34 nice指令:设置优先级 5.35 procinfo指令:显示系统状态 5.36 ps指令:报告程序状况 5.37 pstree指令:以树状图显示程序 5.38 reboot指令:重新启动 5.39 renice指令:调整优先级 5.40 rlogin指令:远端登录 5.41 rsh指令:远端登录的shell 5.42 rwho指令:查看系统用户 5.43 screen指令:多重视窗管理程序 5.44 shutdown指令:系统关机 5.45 skill指令:工作行程资讯与管理 5.46 sleep指令:休眠 5.47 su指令:变更用户身份 5.48 sudo指令:以其他身份来执行 5.49 suspend指令:暂停执行shell 5.50 swatch指令:系统监控程序 5.51 tload指令:显示系统负载 5.52 top指令:显示进程信息 5.53 uname指令:显示系统信息 5.54 useradd指令:建立用户账号 5.55 userconf指令:设置用户账号 5.56 userdel指令:删除用户账号 5.57 usermod指令:修改用户账号 5.58 vlock指令:锁定终端 5.59 w指令:显示登录系统的用户信息 5.60 who指令:显示系统用户信息 5.61 whoami指令:显示用户名 5.62 whois指令:查找用户/域名信息 第6天 系统设置指令 6.1 alias指令:设置指令的别名 6.2 apmd指令:高级电源管理 6.3 aumix指令:设置音效设备 6.4 bind指令:显示或者设置按键组合 6.5 chkconfig指令:设置系统的应用程序 6.6 chroot指令:改变根目录 6.7 clock指令:系统RTC时间设置 6.8 crontab指令:设置计时器 6.9 declare指令:声明 shell 变量 6.10 depmod指令:模块关系 6.11 dircolors指令:ls指令对应的显示颜色设置 6.12 dmesg指令:显示内核信息 6.13 enable指令:激活或关闭shell内建指令 6.14 eval指令:执行多个指令 6.15 export指令:设置或显示环境变量 6.16 fbset指令:设置帧缓冲区 6.17 grpconv指令:开启群组的投影密码 6.18 grpunconv 指令:关闭群组的投影密码 6.19 hwclock指令:显示与设定硬件时钟(rtc) 6.20 insmod指令:载入模块 6.21 kbdconfig指令:设置键盘类型 6.22 lilo指令:引导安装程序 6.23 liloconfig指令:设置程序的载入 6.24 lsmod 指令:显示Linux内核的模块信息 6.25 minfo指令:显示MS-DOS文件系统的各项参数 6.26 mkkickstart 指令:建立安装的组态文件 6.27 modinfo指令:显示内核信息 6.28 modprobe 指令:自动处理可载入模块 6.29 moouseconfig指令:设置鼠标相关参数 6.30 ntsysv指令:设置系统的各种服务 6.31 passwd指令:设置密码 6.32 pwconv指令:开启用户的投影密码 6.33 pwunconv 指令:关闭用户的投影密码 6.34 rdate 指令:显示其他主机的日期与时间 6.35 reset指令:设置终端机状态 6.36 resize指令:设置终端机视窗的大小 6.37 rmmod指令:删除模块 6.38 rpm指令:管理RPM包 6.39 set指令:设置shell 6.40 setconsole指令:设置系统终端 6.41 setenv指令:查询或显示环境变量 6.42 setup指令:设置公用程序 6.43 sndconfig指令:设置声卡 6.44 timeconfig指令:设置时区 6.45 ulimit指令:控制shell程序的资源 6.46 unalias指令:删除别名 6.47 unset指令:删除变量或函数 6.48 up2date指令:更新Linux系统 6.49 vmstat指令:显示虚拟内存空间 第7天 其他常见指令 7.1 as指令:标准GNU汇编程序 7.2 autoconf指令:产生配置脚本 7.3 autoheader指令:为configure产生模板头文件 7.4 autoreconf指令:更新已经生成的配置文件 7.5 autoscan指令:生成configure.in模板文件 7.6 autoupdate 指令:更新 configure.in文件 7.7 gcc指令:GNU的C和C++编译器 7.8 gdb指令:GNU调试器 7.9 gdbserver指令:远端GNU服务器 7.10 ld指令:链接目标文件和库文件 7.11 make指令:编译内核或模块 7.12 nm指令:显示目标文件中的符号 7.13 startx指令:启动x-Windows图形界面 7.14 xhost指令:设置X服务器的访问权限 7.15 xinit指令:启动x-Windows 7.16 xlsclients 指令:显示正在运行的 X程序 7.17 xlsfonts指令:显示目前X服务器可使用的字体 7.18 xset指令:设置x-Windows

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧