精华内容
下载资源
问答
  • 用户空间与内核通信方式有哪些? 系统调用,提供特定的用户空间与内核空间的信息传递。 信号,内核空间出现一些异常时候会发送信号给进程,如SIGSEGV、SIGILL、SIGPIPE等。 /proc,proc可以读取内核空间的信息并且...

    用户空间与内核通信方式有哪些?

    1. 系统调用,提供特定的用户空间与内核空间的信息传递。
    2. 信号,内核空间出现一些异常时候会发送信号给进程,如SIGSEGV、SIGILL、SIGPIPE等。
    3. /proc,proc可以读取内核空间的信息并且设置部分属性的值,需要循环检测。
    4. 文件,可以通过指定文件的读写操作来实现通信,但是流程不够实时,需要循环检测来实现。
    5. netlink,类似socket通信方式,可以读写大量的数据,实现稍微复杂。
    6. ioctl,可以实现数据量比较少时候的通信。
    展开全文
  • Linux 用户态和内核态由于 CPU 权限的限制,通信并不像想象中的使用进程间通信方式那么简单,今天这篇文章就来看看 Linux 用户态和内核态究竟有哪些通信方式。 我们平常在写代码时,一般是在用户空间,通过系统调用...
  • Linux 用户态和内核态由于 CPU 权限的限制,通信并不像想象中的使用进程间通信方式那么简单,今天这篇文章就来看看 Linux 用户态和内核态究竟有哪些通信方式。 我们平常在写代码时,一般是在用户空间,通过...

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫。

    Linux 用户态和内核态由于 CPU 权限的限制,通信并不像想象中的使用进程间通信方式那么简单,今天这篇文章就来看看 Linux 用户态和内核态究竟有哪些通信方式。

    我们平常在写代码时,一般是在用户空间,通过系统调用函数来访问内核空间,这是最常用的一种用户态和内核态通信的方式。(关于 Linux 用户态和内核态可以参考 xx)

    除此之外,还有以下四种方式:

    • procfs(/proc)
    • sysctl(/proc/sys)
    • sysfs(/sys)
    • netlink 套接口

    procfs(/proc)

    procfs进程文件系统 的缩写,它本质上是一个伪文件系统,为什么说是 文件系统呢?因为它不占用外部存储空间,只是占用少量的内存,通常是挂载在 /proc 目录下。

    我们在该目录下看到的一个文件,实际上是一个内核变量。内核就是通过这个目录,以文件的形式展现自己的内部信息,相当于 /proc 目录为用户态和内核态之间的交互搭建了一个桥梁,用户态读写 /proc 下的文件,就是读写内核相关的配置参数。

    比如常见的 /proc/cpuinfo/proc/meminfo/proc/net 就分别提供了 CPU、内存、网络的相关参数。除此之外,还有很多的参数,如下所示:

    root@ubuntu:~# ls /proc/
    1     1143  1345  1447  2     2292  29   331   393  44    63    70    76   acpi       diskstats    irq          locks         sched_debug    sysvipc            zoneinfo
    10    1145  1357  148   20    23    290  332   396  442   64    7019  77   asound     dma          kallsyms     mdstat        schedstat      thread-self
    1042  1149  1361  149   2084  2425  291  34    398  45    65    7029  8    buddyinfo  driver       kcore        meminfo       scsi           timer_list
    1044  1150  1363  15    2087  25    3    3455  413  46    66    7079  83   bus        execdomains  keys         misc          self           timer_stats
    1046  1151  1371  16    2090  256   30   35    418  47    6600  7080  884  cgroups    fb           key-users    modules       slabinfo       tty
    1048  1153  1372  17    21    26    302  36    419  5     67    71    9    cmdline    filesystems  kmsg         mounts        softirqs       uptime
    11    1190  1390  18    22    27    31   37    420  518   6749  72    96   consoles   fs           kpagecgroup  mtrr          stat           version
    1126  12    143   182   2214  28    32   373   421  524   68    73    97   cpuinfo    interrupts   kpagecount   net           swaps          version_signature
    1137  1252  1434  184   2215  280   327  38    422  525   69    74    98   crypto     iomem        kpageflags   pagetypeinfo  sys            vmallocinfo
    1141  13    144   190   2262  281   33   39    425  5940  7     75    985  devices    ioports      loadavg      partitions    sysrq-trigger  vmstat

    可以看到,这里面有很多的数字表示的文件,这些其实是当前系统运行的进程文件,数字表示进程号(PID),每个文件包含该进程所有的配置信息,包括进程状态、文件描述符、内存映射等等,我们可以看下:

    root@ubuntu:~# ls /proc/1/
    attr/            cmdline          environ          io               mem              ns/              pagemap          schedstat        stat             timers
    autogroup        comm             exe              limits           mountinfo        numa_maps        personality      sessionid        statm            uid_map
    auxv             coredump_filter  fd/              loginuid         mounts           oom_adj          projid_map       setgroups        status           wchan
    cgroup           cpuset           fdinfo/          map_files/       mountstats       oom_score        root/            smaps            syscall          
    clear_refs       cwd/             gid_map          maps             net/             oom_score_adj    sched            stack            task/

    综上,内核通过一个个的文件来暴露自己的系统配置信息,这些文件,有些是只读的,有些是可写的,有些是动态变化的,比如进程文件,当应用程序读取某个 /proc/ 文件时,内核才会去注册这个文件,然后再调用一组内核函数来处理,将相应的内核参数拷贝到用户态空间,这样用户读这个文件就可以获取到内核的信息。一个大概的图示如下所示:

    431521-20190603105337542-1918784356.png

    sysctl

    我们熟悉的 sysctl 是一个 Linux 命令,man sysctl 可以看到它的功能和用法。它主要是被用来修改内核的运行时参数,换句话说,它可以在内核运行过程中,动态修改内核参数。

    它本质上还是用到了文件的读写操作,来完成用户态和内核态的通信。它使用的是 /proc 的一个子目录 /proc/sys。和 procfs 的区别在于:

    procfs 主要是输出只读数据,而 sysctl 输出的大部分信息是可写的。

    例如,我们比较常见的是通过 cat /proc/sys/net/ipv4/ip_forward 来获取内核网络层是否允许转发 IP 数据包,通过 echo 1 > /proc/sys/net/ipv4/ip_forward 或者 sysctl -w net.ipv4.ip_forward=1 来设置内核网络层允许转发 IP 数据包。

    同样的操作,Linux 也提供了文件 /etc/sysctl.conf 来让你进行批量修改。

    sysfs

    sysfs 是 Linux 2.6 才引入的一种虚拟文件系统,它的做法也是通过文件 /sys 来完成用户态和内核的通信。和 procfs 不同的是,sysfs 是将一些原本在 procfs 中的,关于设备和驱动的部分,独立出来,以 “设备树” 的形式呈现给用户。

    sysfs 不仅可以从内核空间读取设备和驱动程序的信息,也可以对设备和驱动进行配置。

    我们看下 /sys 下有什么:

    # ls /sys
    block  bus  class  dev  devices  firmware  fs  hypervisor  kernel  module  power

    可以看到这些文件基本上都跟计算机的设备和驱动等息息相关的。更多关于这些文件的解释大家可以自行了解,这里就不过多展开了。

    netlink 是 Linux 用户态与内核态通信最常用的一种方式。Linux kernel 2.6.14 版本才开始支持。它本质上是一种 socket,常规 socket 使用的标准 API,在它身上同样适用。比如创建一个 netlink socket,可以调用如下的 socket 函数:

    #include <asm/types.h>
    #include <sys/socket.h>
    #include <linux/netlink.h>
    
    netlink_socket = socket(AF_NETLINK, socket_type, netlink_family);

    netlink 这种灵活的方式,使得它可以用于内核与多种用户进程之间的消息传递系统,比如路由子系统,防火墙(Netfilter),ipsec 安全策略等等。

    引申:

    net-tools 工具通过 procfs(/proc) 和 ioctl 系统调用去访问和改变内核网络参数配置,而 iproute2 则通过 netlink 套接字接口与内核通信,前者已经被淘汰了,后者逐步成为标准。

    总结

    Linux 用户态和内核态通信主要的四种方式,其中 netlink 和 procfs 是最常见的方式。


    后台回复“加群”,带你进入高手如云交流群

    我的公众号 「Linux云计算网络」(id: cloud_dev) ,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,分享的内容包括但不限于 Linux、网络、云计算虚拟化、容器Docker、OpenStack、Kubernetes、工具、SDN、OVS、DPDK、Go、Python、C/C++编程技术等内容,欢迎大家关注。

    431521-20190415111037844-1058636985.png

    参考:

    https://www.ibm.com/developerworks/cn/linux/l-kerns-usrs/index.html

    https://fasionchan.com/blog/2017/06/16/procfs-wei-wen-jian-xi-tong-yuan-li/

    https://zh.wikipedia.org/wiki/Netlink

    转载于:https://www.cnblogs.com/bakari/p/10966303.html

    展开全文
  • Linux内核相关

    2020-08-02 22:06:14
    1. 用户空间与内核通信方式有哪些? 1.系统调用  get_user(x,ptr):在内核中被调用,获取用户空间指定地址的数值并保存到内核变量x中。  put_user(x,ptr):在内核中被调用,将内核空间的变量x的数值保存到到用户...

    1. 用户空间与内核通信方式有哪些?⭐⭐⭐⭐⭐

    转载
    1.使用API(最常用)
     get_user(x,ptr):在内核中被调用,获取用户空间指定地址的数值并保存到内核变量x中。
     put_user(x,ptr):在内核中被调用,将内核空间的变量x的数值保存到到用户空间指定地址处。
    copy_from_user()/copy_to_user():主要应用于设备驱动读写函数中,通过系统调用触发。
    2.proc虚拟文件系统:和sysfs文件系统类似,也可以作为内核空间和用户空间交互的手段。
    3.使用mmap系统调用:可以将内核空间的地址映射到用户空间。
    一方面可以在driver中修改Struct file_operations结构中的mmap函数指针来重新实现一个文件对应的映射操作。另一方面,也可以直接打开/dev/mem文件,把物理内存中的某一页映射到进程空间中的地址上。
    4.信号:从内核空间向进程发送信号。
    用户程序出现重大错误,内核发送信号杀死相应进程。
    5.netlink:netlink socket提供了一组类似于BSD风格的API,用于用户态和内核态的IPC(进程间通信)。
    6.文件:当处于内核空间的时候,直接操作文件,将想要传递的信息写入文件,然后用户空间可以读取这个文件便可以得到想要的数据了。

    2. 系统调用的作用

    什么是系统调用?
    Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。

    1.系统调用可以为用户空间提供访问硬件资源的统一接口,以至于应用程序不必去关注具体的硬件访问操作。
    比如,读写文件时,应用程序不用去管磁盘类型,甚至于不用关心是哪种文件系统。
    2.系统调用可以对系统进行保护,保证系统的稳定和安全。系统调用的存在规定了用户进程进入内核的具体方式。

    换句话说,用户访问内核的路径是事先规定好的,只能从规定位置进入内核,而不准许肆意跳入内核。有了这样的进入内核的统一访问路径限制才能保证 内核的安全。我们可以形象地描述这种机制:作为一个游客,你可以买票要求进入野生动物园,但你必须老老实实地坐在观光车上,按照规定的路线观光游览。当然,不准下车,因为那样太危险,不是让你丢掉小命,就是让你吓坏了野生动物。

    3. 内核态,用户态的区别

    转载1
    转载2
    用户空间:指的就是用户可以操作和访问的空间,这个空间通常存放我们用户自己写的数据等。
    内核空间:是系统内核来操作的一块空间,这块空间里面存放系统内核的函数、接口等。
    在用户空间下执行,我们把此时运行得程序的这种状态成为用户态,而当这段程序执行在内核的空间执行时,这种状态称为内核态。
    用户态切换到内核态的3种方式
    a.系统调用
    b.异常
    c.外围设备的中断

    4. Bootloader 内核 根文件的关系⭐⭐⭐⭐

    一个嵌入式Linux系统从软件角度看可以分为四个部分:引导加载程序(Bootloader),Linux内核,文件系统,应用程序。
    1、引导加载程序。包括固化在固件中的boot代码(可选)和BootLoader两大部分。在嵌入式系统中,通常并没有像BIOS那样的固件程序,因此整个系统的加载启动任务就完全由BootLoader来完成。一个基于ARM9 TDMI core的嵌入式系统中,系统在上电或复位时通常从地址0x00000000处开始执行,而这个地址处安排的通常就是系统的BootLoader程序。目前比较流行的两款bootloader是vivi和u-boot.
    2、Linux内核。
    3、文件系统。包括根文件系统和建立于flash设备之上的文件系统。
    4、用户应用程序。

    5. 为什么需要BootLoader

    参考
    简单的说,BootLoader就是在操作系统运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统做好准备。对于Bootloader的启动过程又分为两个阶段stage1和stage2。
    stage1全部由汇编编写,它的主要工作是(1)初始化硬件设备、(2)为加载Bootlodader的stage2准备RAM空间(3)拷贝Bootloader的stage2到RAM空间(4)设置好堆栈段为stager2的C语言环境做准备。
    stage2全部由C语言编写,其的主要工作是(1)初始化本阶段要使用到的硬件设备(2)将内核映像和根文件系统映像从 flash 上读到RAM (3)调用内核
    每种不同的CPU体系结构都有不同的Bootloader。除了依赖于CPU的体系结构外,Bootloader还依赖于具体的嵌入式板级设备的配置,比如板卡的硬件地址分配,外设芯片类型等。对于两块不同的开发板而言,即使他们是基于同一种CPU而构建的,但是如果他们的硬件资源或配置不一致的话,想要在一块开发板上运行Bootloader程序也能在另一块板子上运行,还是需要做修改。

    6. Linux内核同步方式总结

    !!!转载
    Linux设备驱动中必须解决的一个问题是多个进程对共享资源的并发访问,并发访问会导致竞态,linux提供了多种解决竞态问题的方式,这些方式适合不同的应用场景。
    Linux内核是多进程、多线程的操作系统,它提供了相当完整的内核同步方法。内核同步方法列表如下:
    1、中断屏蔽
    在单CPU范围内避免竞态的一种简单方法是在进入临界区之前屏蔽系统的中断。由于linux内核的进程调度等操作都依赖中断来实现,内核抢占进程之间的并发也就得以避免了。
    2、原子操作
    原子操作指的是在执行过程中不会被别的代码路径所中断的操作。
    3、自旋锁
    4、读写自旋锁
    5、顺序锁
    6、信号量
    7、读写信号量
    8、BKL(大内核锁)
    9、Seq锁

    并发与竞态
    定义
    在linux中,主要的竞态发生在如下几种情况
    解决竞态问题的途径
    临界区和竞争条件
    死锁
    自旋锁和信号量区别
    1、由于争用信号量的进程在等待锁重新变为可用时会睡眠,所以信号量适用于锁会被长时间持有的情况。
    2、相反,锁被短时间持有时,使用信号量就不太适宜了,因为睡眠引起的耗时可能比锁被占用的全部时间还要长。
    3、由于执行线程在锁被争用时会睡眠,所以只能在进程上下文中才能获取信号量锁,因为在中断上下文中(使用自旋锁)是不能进行调度的。
    4、你可以在持有信号量时去睡眠(当然你也可能并不需要睡眠),因为当其它进程试图获得同一信号量时不会因此而死锁,(因为该进程也只是去睡眠而已,而你最终会继续执行的)。
    5、在你占用信号量的同时不能占用自旋锁,因为在你等待信号量时可能会睡眠,而在持有自旋锁时是不允许睡眠的。
    6、信号量锁保护的临界区可包含可能引起阻塞的代码,而自旋锁则绝对要避免用来保护包含这样代码的临界区,因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一进程企图获取本自旋锁,死锁就会发生。
    7、信号量不同于自旋锁,它不会禁止内核抢占(自旋锁被持有时,内核不能被抢占),所以持有信号量的代码可以被抢占,这意味着信号量不会对调度的等待时间带来负面影响。

    7. 为什么自旋锁不能睡眠而在拥有信号量时就可以?

    参考
    自旋锁禁止处理器抢占;而信号量不禁止处理器抢占。
    基于这个原因,如果自旋锁在锁住以后进入睡眠,由于不能进行处理器抢占,其他系统进程将都不能获得CPU而运行,因此不能唤醒睡眠的自旋锁,因此系统将不响应任何操作(除了中断或多核的情况,下面会讨论)。而信号量在临界区睡眠后,其他进程可以用抢占的方式继续运行,从而可以实现内存拷贝等功能而使得睡眠的信号量程序由于获得了等待的资源而被唤醒,从而恢复了正常的代码运行。
    当然,自旋锁的睡眠的情况包含考虑多核CPU和中断的因素。自旋锁睡眠时,只是当前CPU的睡眠以及当前CPU的禁止处理器抢占,所以,如果存在多个CPU,那么其他活动的CPU可以继续运行使操作系统功能正常,并有可能完成相应工作而唤醒睡眠了的自旋锁,从而没有造成系统死机;自旋锁睡眠时,如果允许中断处理,那么中断的代码是可以正常运行的,但是中断通常不会唤醒睡眠的自旋锁,因此系统仍然运行不正常。

    自旋锁不能睡眠:
    A获得锁睡眠,B在等锁怎么办,可能会等很久哦,B就一直自旋等着,光等着不干活。获得锁,本来就是要操作一些共享资源,所以赶快的,别墨迹,还睡个球。
    禁止中断不能睡眠:
    禁止中断就是希望不被打扰,赶紧干完自己该做的事,还睡觉,我靠,还想不想干了。当硬件中断来的时候,这种情况不能睡眠,想想也对,你来强行打断人家,还想带着人家去睡,怎么可以,中断上下文不应该睡眠,只有进程上下文可以睡,技术当然可以实现,但没有意义。
    spinlock的初衷是关调度,别人别和我抢这个临界区,同时也不让其他核抢。
    关中断时不能睡眠,因为睡眠依赖调度器,调度器通过时钟中断判断何时唤醒任务。

    8. Bootloader多数有两个阶段的启动过程:⭐⭐⭐

    参考
    对于Bootloader的启动过程分为两个阶段stage1和stage2。
    stage1全部由汇编编写,它的主要工作是
    (1)初始化硬件设备
    (2)为加载Bootlodader的stage2准备RAM空间
    (3)拷贝Bootloader的stage2到RAM空间
    (4)设置好堆栈段为stager2的C语言环境做准备。
    stage2全部由C语言编写,其的主要工作是
    (1)初始化本阶段要使用到的硬件设备
    (2)将内核映像和根文件系统映像从 flash 上读到RAM
    (3)调用内核

    9. linux下检查内存状态的命令

    查看内存状态的命令是:top
    查看正在运行的进程和系统负载信息,包括cpu负载、内存使用、各个进程所占系统资源等,top命令以一定频率动态更新这些统计信息。
    查看进程的命令是:ps -a
    free 命令会显示系统内存的使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存等。
    cat /proc/meminfo

    10. Linux内核的组成⭐⭐

    转载
    Linux内核主要由五个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信
    1.进程调度(SCHED):控制进程对CPU的访问。当需要选择下一个进程运行时,由调度程序选择最值得运行的进程。可运行进程实际上是仅等待CPU资源的进程,如果某个进程在等待其它资源,则该进程是不可运行进程。Linux使用了比较简单的基于优先级的进程调度算法选择新的进程。
    2.内存管理(MM):允许多个进程安全的共享主内存区域。Linux 的内存管理支持虚拟内存,即在计算机中运行的程序,其代码,数据,堆栈的总量可以超过实际内存的大小,操作系统只是把当前使用的程序块保留在内存中,其余的程序块则保留在磁盘中。必要时,操作系统负责在磁盘和内存间交换程序块。内存管理从逻辑上分为硬件无关部分和硬件有关部分。硬件无关部分提供了进程的映射和逻辑内存的对换;硬件相关的部分为内存管理硬件提供了虚拟接口。
    3.虚拟文件系统(Virtual File System,VFS):隐藏了各种硬件的具体细节,为所有的设备提供了统一的接口,VFS提供了多达数十种不同的文件系统。虚拟文件系统可以分为逻辑文件系统和设备驱动程序。逻辑文件系统指Linux所支持的文件系统,如ext2,fat等,设备驱动程序指为每一种硬件控制器所编写的设备驱动程序模块。
    4.网络接口(NET):提供了对各种网络标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程序。网络协议部分负责实现每一种可能的网络传输协议。网络设备驱动程序负责与硬件设备通讯,每一种可能的硬件设备都有相应的设备驱动程序。
    5.进程间通讯(IPC) :主要用于控制不同进程之间在用户空间的同步、数据共享和交换。由于不用的用户进程拥有不同的进程空间,因此进程间的通信要借助于内核的中转来实现。一般情况下,当一个进程等待硬件操作完成时,会被挂起。当硬件操作完成,进程被恢复执行,而协调这个过程的就是进程间的通信机制。

    11. 系统调用read()/write(),内核具体做了哪些事情

    参考
    内核空间,scull_read() 通过file_operations结构与scull_fops->read联系
    用户空间read()–>内核空间sys_read()–>scull_fops.read–>scull_read();
    read 系统调用发出到结束处理的过程包括两个部分:用户空间的处理、核心空间的处理。用户空间处理部分是系统调用从用户态切到核心态的过程。核心空间处理部分则是 read 系统调用在 linux 内核中处理的整个过程。
    Read 系统调用在用户空间中的处理过程
    Read 系统调用,当调用发生时,库函数在保存 read 系统调用号以及参数后,陷入 0x80 中断。这时库函数工作结束。Read 系统调用在用户空间中的处理也就完成了。
    Read 系统调用在核心空间中的处理过程
    0x80 中断处理程序接管执行后,先检察其系统调用号,然后根据系统调用号查找系统调用表,并从系统调用表中得到处理 read 系统调用的内核函数 sys_read ,最后传递参数并运行 sys_read 函数。至此,内核真正开始处理 read 系统调用(sys_read 是 read 系统调用的内核入口)。
    Read 系统调用在核心空间中处理的层次模型
    对于磁盘的一次读请求,首先经过虚拟文件系统层(vfs layer),其次是具体的文件系统层(例如 ext2),接下来是 cache 层(page cache 层)、通用块层(generic block layer)、IO 调度层(I/O scheduler layer)、块设备驱动层(block device driver layer),最后是物理块设备层(block device layer)

    展开全文
  • 对于见到的每个问题,先列出来,再搜索资源学习,最后总结为答案。 1.linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些? 答:

    对于见到的每个问题,先列出来,再搜索资源学习,最后总结为答案。

    1.linux中内核空间及用户空间的区别?

    答:区别有很多,简言概之就是,Linux系统采取两级保护机制,对应两种不同的操作权限,内核空间权限高于用户空间权限,内核空间和用户空间都有属于自己的虚拟空间,在32位系统中,cpu最高有32位寻址范围,即对应4G空间,内核空间被划分在高1G虚拟空间,用户空间在低3G。普通应用程序运行在用户空间,执行一些贴近用户的低权限操作,系统内核程序,操作硬件的驱动程序等一些要求高级权限的程序运行在内核空间。用户空间程序不能直接访问内核空间的数据,内核空间程序也一样不能直接访问属于用户进程空间的数据,用户空间和内核空间之间的通信必须通过一些特定的方法。

    2.用户空间与内核通信方式有哪些?

    答:通信方式也有很多,但常用的也就这几种:

    a)首先想到的是系统调用,用户空间进程通过系统调用进入内核空间,访问指定的内核空间数据;

    b).其次是驱动程序,用户空间进程可以使用封装后的系统调用接口访问驱动设备节点,以和运行在内和空间的驱动程序通信;

    c).还有就是,proc文件系统,proc文件系统的主要功能是在内核空间提供一套机制为用户空间方便的查询,查看,设置内核信息,多用于查询类操作。(但我觉得有很多人把它和/dev文件系统的作用混淆了,也许是我认识还不够深刻。);

    d).共享内存mmap,在代码中调用接口,实现内核空间与用户空间的地址映射,在实时性要求很高的项目中为首选,省去拷贝数据的时间等资源,但缺点是不好控制;

    e).最后,copy_to_user()、copy_from_user(),是在驱动程序中调用接口,实现用户空间与内核空间的数据拷贝操作,应用于实时性要求不高的项目中。

    3.linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化,高端内存概念?

    答:以32位机器为例,cpu最大寻址范围为4G,Linux系统将4G虚拟地址空间划分为高1G,低3G,低3G虚拟空间属于用户空间,都是经过映射的线性地址,供用户进程空间使用,高1G并非都是像用户空间一样都是映射过的线性空间,Linux系统将高1G划分为三部分,DMA区,常规区,高端内存,其中0-896都是映射过的线性空间,剩下的896-1024即高端内存,这段高端内存都是未经过映射的虚拟地址,Linux系统利用这些有限的虚拟地址,临时动态的映射到大于896M的物理空间地址,实现了利用有限的虚拟地址访问到物理内存的所有地址。malloc用于用户空间进程申请内存空间,kmallc和vmalloc在内核空间使用,kmalloc申请到的内存空间,是线性连续的,可以用于dma。vmalloc申请的内存是逻辑连续的,但是物理地址不连续,常用与申请大的内存,请注意vmalloc可能会睡眠,在中断,阻塞的环境下不能使用。至于虚拟地址到物理地址的转化,用户空间和内和空间采用不同的映射机制。用户空间的地址映射经过mmu(内存管理单元)管理。而内核空间的虚拟地址到物理地址的映射是一一对应的,例如虚拟空间地址0xc0000004,对应的物理地址空间地址为:0xc0000004 - 0xc0000000 = 0x04,以此类推。(基于个人理解)。

    3. linux中中断的实现机制,tasklet与workqueue的区别及底层实现区别?为什么要区分上半部和下半部?

    答:Linux中断分为硬件中断和内部中断(异常),调用过程:外部中断产生->发送中断信号到中断控制器->通知处理器产生中断的中断号,让其进一步处理。对于中断上半部和下半部的产生,为了中断处理过程中被新的中断打断,将中断处理一分为二,上半部登记新的中断,快速处理简单的任务,剩余复杂耗时的处理留给下半部处理,下半部处理过程中可以被中断,上半部处理时不可被中断。至于tasklet和工作队列,在网上看了一圈,由于不常用,看的有点迷糊,个人理解: 两者都是中断下半部的一种实现方法,区别在于,tasklet支持smp,不可睡眠。工作队列基于线程的封装,因此支持睡眠。

    4.linux中断的响应执行流程?

    答:处理器收到来自中断控制器的中断处理请求,保存中断上下文,跳转到中断对应的处理处,(快速完成中断中断上半部,中断上半部返回后执行中断下半部。如果做了上下半部处理的话),中断处理函数返回时恢复现场。

    5.谈谈Linux的同步机制。

    答:首先说说常见的同步接口,包括进程同步,信号量,自旋锁,互斥锁,条件变量,读写锁。个人理解:多进程并发一般考虑使用信号量机制,在线程并发时多采用互斥锁,条件变量,个人觉得条件变量在某些角度就是线程版的信号量实现,因为两者都是在考虑持有锁时间较长情况下使用,而互斥锁,自旋锁一般都是用在持有锁时间不会很长的情况下,在自旋锁有使用意义的前提下,如果持锁时间 会非常短则自旋锁效率高于互斥锁,否则应该使用互斥锁,因为互斥锁会持续占有cpu资源,不宜过长,而互斥锁会导致抢不到锁的线程睡眠,进入等待队列。互斥锁和自旋锁都可以用在进程上下文,而在中断上下文只能使用自旋锁,因为互斥锁会睡眠。

    6./dev/下面的设备文件是怎么创建出来的?

    答:普遍说法有三种方式,devfs机制,udev机制,再有一个就是手动创建设备节点。谈谈个人见解:devfs机制从来没用过,应该是2.6以前的内核使用的;udev,其实就是现在常用的device_create()、class_create()这一套接口,所谓udev是上层用户空间程序,是基于驱动中创建使用了这两个接口而起作用的,但是udev在日常开发中几乎接触不到,我们只需在驱动中调用创建节点的这两个API就ok了,剩下的工作就交给udev去做了,有想深究它具体实现原理的那就自己去研究吧,我觉得会用就行了;mknod ,新手最常用的一种创建设备节点方法,但并非入门后就再没有用途,在某些情境下,或许有人不想使用udev机制,于是把节点创建工作写在脚本里,这样也是无可厚非的。

    7.原子操作该怎么理解?

    答:原子操作,就是开始执行到执行结束期间不会被打断的操作单元。

    8.insmod一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?

    答:分别会执行module_init()和module_exit()指定的init函数和exit函数。要注意的就是尽量使在init函数中出现的资源申请及使用有对应的释放操作在exit中,init申请,eixt释放。卸载出现的异常?那很稀松平常了,大多数都是资源使用完,没释放,但是模块却卸载了。

    9.在驱动调试过程中遇到过oops没?你是怎么处理的?

    答:遇到过,这种类似的段错误什么的其实最好处理了,因为它有call trace,根据堆栈信息去代码里面查看就行了,如果代码中看不到明显低级错误,就printk联机调试呗,这对调试驱动的人来说是成就感来的最容易的地方,然而这种很少。

    8.ioctl和unlock_ioctl有什么区别?

    答:ioctl是老的内核版本中的驱动API,unlock_ioctl是当下常用的驱动API,区别在于ioctl调用前后,使用了大内核锁(网上这么说的,半信半疑去了解了下啥叫个大内核锁),而unlock_ioctl顾名思义就是没加大内核锁的新接口呗,改变的只是驱动调的方法,用户应用程序调用的接口不变。谈谈大内核锁吧,大内核锁是Linux hacker在应付多处理器初期提出的一种锁,目的在于当一个处理核心在运行内核时,加上大内核锁,不让其他cpu核心同时运行内核程序,显然这样是有用的,然而这样大大降低了多处理器的存在意义,于是跟随时代更迭,大内核锁被一步一步的剔除,ioctl接口的升级就是典范!我觉得这样的问题太没有意义了,对开发有多大用处?

    9.驱动中操作物理绝对地址为什么要先ioremap?

    答:ioremp是内核中用来将外设寄存器物理地址映射到主存上去的接口,即将io地址空间映射到虚拟地址空间上去,便于操作。为什么非要映射呢,因为保护模式下的cpu只认虚拟地址,不认物理地址,给它物理地址它并不帮你做事,所以你要操作外设上的寄存器必须先映射到虚拟内存空间,拿着虚拟地址去跟cpu对接,从而操作寄存器。

    10.设备驱动模型三个重要成员是?platfoem总线的匹配规则是?在具体应用上要不要先注册驱动再注册设备?有先后顺序没?

    答:总线,设备,驱动。匹配规则就是当有一个新的设备挂起时,总线被唤醒,match函数被调用,用device名字去跟本总线下的所有驱动名字去比较。相反就是用驱动的名字去device链表中和所有device的名字比较。如果匹配上,才会调用驱动中的probe函数,否则不调用。至于先后顺序,鉴于个人理解,不会有影响,不管谁先谁后,bus都会完成匹配工作。谈谈对Linux设备驱动模型的认识:设备驱动模型的出现主要有三个好处,设备与驱动分离,驱动可移植性增强;设备驱动抽象结构以总线结构表示看起来更加清晰明了,谁是属于哪一条bus的;最后,就是大家最熟悉的热插拔了,设备与驱动分离,很好的奠定了热插拔机制。

    11.linux中RCU原理?

    答:rcu是2.6出现的一种读写锁,可以说是老的读写锁的升级版,主要用在链表这种数据结构上,经典使用场景是多读者少写者的情况,rcu允许多个读者一个写者共同操作数据而不必加锁,这是经典用法,若出现多个写者时,写者与写者之间就得自己手动同步。当要删除一个节点时,删除后并不会马上释放节点,而是会等待在删除动作之前已经开始读该节点的读者都完成读操作之后才会释放此节点,这段时间被称为宽限期。

    12.谈谈Linux软中断?

    答:Linux系统中的软中断是专为一些不是不是特别要紧的耗时任务而产生的一种机制,多数用在中断处理过程中,典型应用就是用于中断下半部,tasklet机制就是基于软中断的典型下半部应用。软中断就是结合任务调度,延迟处理等让守护进程去处理一些不是特别紧急又耗时的任务。

    13.linux系统实现原子操作有哪些方法?

    答:这个问题网上回答五花八门,答非所问。提到原子操作我首先想到的是针对整形的原子操作,atomic_t类型,这里面有一整套针对整形的原子操作API可以调用。既然整型能原子操作,那其他也应该可以吧,结合原子操作的定义,要想对其他类型结构实现原子操作,那就加锁咯,将需要原子操作的部分放在临界区。

    14.linux中系统调用过程?

    答:系统调用,比如open(),它并不是真正的系统调用实现函数,其实它只是一个c库函数,内部实现就做了两件事,先把系统调用号传递给内核,最后拉起一次软中断,自此cpu进入内核态运行,内核在软中断向量表中找出对应的中断类型,根据中断类型找到对应的软中断执行函数,执行函数根据系统调用号,在系统调用号表里面找到对应的系统调用函数。

    15.谈谈linux内核的启动过程(源代码级)?

    答:首先内核镜像自解压,解压完之后从head.s开始运行,即引导内核,在内核引导期间将会设置内核参数。随后,跳转到第一个c函数start_kernel(),进入内核启动阶段,在内核启动过程中进行一些必要的硬件初始化工作,在内核启动的最后,挂载文件系统,然后创建第一个用户空间进程,init进程,进一步完成驱动挂载,用户服务初始化工作。

    16.谈谈Linux调度原理?

    答:Linux将进程按权限分为两大类,常规进程和实时进程,常规进程对应一种调度算法,实时进程有两种对应着两种不同的调度算法。进程按照状态又可以分为几种,常见的状态有,运行态,可中断睡眠态,不可中断睡眠态,停止态。处于运行态的进程根据调度算法接受调度在cpu上运行。

    17.谈谈对Linux网络子系统的认识?

    答:网络子系统可以概括描述为:应用程序-》系统调用接口(主要是指socket接口)-》协议无关接口(有socket实现,提供一套通用接口支持不同的协议)-》网络协议(包括tcp、udp在内的网络协议)-》设备无关接口(有net_device接口组织的一组通用接口将网络协议与各种网络设备联系起来)-》设备驱动(即各种网络设备的驱动程序,负责管理具体的网络设备)-》网络设备(具体的网络硬件设备)。

    18.内核中申请内存有哪几个函数?有什么区别?

    答:只谈谈常见的三个接口,kmalloc(),vmalloc()和__get_free_pages()。kmalloc()操作的空间位于直接映射区(即4G空间中的896M区域),申请到空间物理地址多为连续地址,常用于操作频繁的数据结构,连续地址利于提高访问效率。而对于一些操作不频繁的数据结构可以用vmalloc()申请内存,vmalloc()操作的空间优先选择高端内存,这里申请出的内存物理地址往往不是连续的,所以访问效率不会很高。__get_free_pages()操作的区域跟kmalloc()相同,位于直接映射区,不同的是它申请的是物理页的整倍数大小的内存。

    19.谈谈内核函数mmap的实现机制?

    答:

    展开全文
  • 用户空间与内核通信方式有哪些?字符设备和块设备的区别,请分别列举一些实际的设备说出它们是属于哪一类设备linux中系统调用过程?如:应用程序中read()在linux中执行过程即从用户空间到内核空间?查看驱动模块中...
  • 分享一下 ...用户空间与内核通信方式有哪些? 答案: Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Linux的虚拟地址空间也为0~4G.Linux内核将这4G字节的空间分为两部分。将最高的...
  • linux面试问题宝典

    2021-03-13 21:53:13
    简单介绍: ...用户空间与内核通信方式有哪些? 答案: Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Linux的虚拟地址空间也为0~4G.Linux内核将这4G字节的空间分为两部分。将最高的1G
  • 用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化,高端内存概念? 3:linux中中断的实现机制,tasklet与workqueue的区别及底层实现区别?为什么要区分上半...
  • linux驱动面试题

    2017-09-03 09:31:29
    用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化,高端内存概念? 3:linux中中断的实现机制,tasklet与workqueue的区别及底层实现区别?为什么要区分上...
  • 用户空间与内核通信方式有哪些 linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化,高端内存概念 linux中中断的实现机制,tasklet与workqueue的区别及底层实现区别?为什么要区分上半部和下半部...
  • 用户空间与内核通信方式有哪些   见Linux部分 linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化,高端内存概念   答:以32位机器为例,cpu最大寻址范围为4G,Linux系统将4G虚拟地址空间划分...
  • linux 驱动知识点总结

    千次阅读 2018-02-20 17:38:29
    用户空间与内核通信方式有哪些?A.INTRODUCTION (32位系统) Linux 简化了分段机制,使得虚拟地址(逻辑地址)与线性地址总是一致,因此,Linux的虚拟地址空间也为0~4G(2^32)。 Linux内核将这4G字节的空间...
  • 面试整理

    2020-09-07 15:07:49
    进程和线程 什么是进程,线程,彼此有什么区别 多进程、多线程同步(通讯)的方法 用户线程和内核线程的区别 多进程、多线程的优缺点 ...用户空间与内核通信方式有哪些? 系统调用的作用 内核态,用户态的区别 Boot
  • 理论的东西不常用时就会慢慢的被遗忘,但是找工作就是一个如何让别人相信自己的过程,理论知识就是一个非常重要的途径。 一次次机会在错失,每次想找工作时,...用户空间与内核通信方式有哪些? 答:Linux内核将内存
  • linux驱动笔试题总结

    千次阅读 2016-07-12 12:26:29
    linux驱动笔试题总结试题取之于网络,用之于民。最近在学习linux驱动,驱动开发在笔试的时候考的知识点是有规律可循的,并且这些面点也是平时驱动...1linux中内核空间及用户空间的区别用户空间与内核通信方式有哪些 2li
  • Linux内核知识杂记

    2017-07-29 23:07:00
    2.内核空间和用户空间区别,通信方式有哪些?  Linux简化了分段机制,使得虚拟地址线性地址总是一致,因此,Linux的虚拟地址空间也为0~4G。Linux内核将这4G字节的空间分为两部分。将最高的1G字节(从虚拟地址0...
  • 进程间通信之信号

    2018-04-18 22:26:03
    2. 信号也属于一种模仿软中断机制,是一种异步通信方式,信号可以在用户空间进程和内核之间直接交互。内核可以利用信号来通知用户空间的进程发生了哪些事件。 3. 信号事件两种来源:按键触发的事件使用系统...
  • 内存交换程序装入和链接程序的链接方式冯诺依曼计算机模型详解计算机五大核心组成部分CPU指令结构控制单元运算单元存储单元CPU缓存架构CPU读取存储器数据过程CPU为何要高速缓存带高速缓存的CPU执行计算的流程CPU...
  • 操作系统期末试卷答案

    热门讨论 2009-12-30 11:02:22
    1、进程通信的常用方式有 直接通信 和 间接通信 等。 2、如果P(S1)和P(S2)两个操作在一起,那么P操作的顺序至关重要,一个同步P操作一个互斥P操作在一起时同步 P操作在互斥 P操作前。而两个V操作的次序无关紧要 ...
  • 0.26 库函数是用户进程与内核的桥梁 33 0.27 转义字符与ASCII码 37 0.28 MBR、EBR、DBR和OBR各是 什么 39 第1章 部署工作环境 42 1.1 工欲善其事,必先利其器 42 1.2 我们需要哪些编译器 42 1.2.1 世界顶级编译器GCC...
  • 1.2.6 一颗现代处理器,每秒大概可以执行多少条简单的MOV指令,有哪些主要的影响因素 1.2.7 请分析 MaxCompute 产品分布式技术的关系、当前大数据计算平台类产品的市场现状和发展趋势 1.2.8 对大数据平台中的...
  • 3、用户的观点 操作系统是计算机与用户之间的接口,用户通过这种接口使用计算机。 4、软件的观点 操作系统是程序和数据结构的集合。 5、管理的观点 操作系统是计算机硬件和软件资源的合理而协调的管理者。 6、 操作...
  • COM+是一种复杂的技术,它是几乎所有组件通信方式的基础,实现了事务处理、消息传输服务和对象池。 Microsoft选择这种软件革新方法的原因非常明显:它关注后向兼容性。在过去的这些年中,人们编写了大量Windows第三...
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    这是因为Linux和许多版本的Unix一样,提供了虚拟控制台的访问方式,允许用户在同一时间从控制台(系统的控制台是系统直接相连的监视器和键盘)进行多次登录。每个虚拟控制台可以看作是一个独立的工作站,工作台...
  • CruiseYoung提供的带详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 Oracle Database 9i/10g/11g编程艺术:深入数据库体系结构:第2版(世界顶级专家Thomas Kyte力作) 基本信息 原...

空空如也

空空如也

1 2
收藏数 35
精华内容 14
关键字:

用户空间与内核通信方式有哪些