精华内容
下载资源
问答
  • 搭建了一个微信小程序(WeChatPrintDemo,可从GitHub下载获取)来演示如何用微信,在斑马打印机上打印标签及图像。WeChatPrintDemo的软件实现进行了详尽描述、并指出了在Android上向蓝牙设备特征值写二进制数据的注意...

    现在微信使用越来越便利,最近我在官网论坛找到了一个微信小程序的例子。

    05a89067c9538e1652b5fe04b38557bd.png

           搭建了一个微信小程序(WeChatPrintDemo,可从GitHub下载获取)来演示如何用微信,在斑马打印机上打印标签及图像。WeChatPrintDemo的软件实现进行了详尽描述、并指出了在Android上向蓝牙设备特征值写二进制数据的注意事项。

           WeChatPrintDemo演示了如何从微信小程序扫描,连接ZPL并将其发送到启用BLE的Zebra打印机,以打印标签和图像。有关如何创建微信小程序的详细信息,请访问微信小程序开发者网站,您可以在其中注册开发者帐户,查看API文档,下载SDK和教程。

    https://github.com/ZebraDevs/Zebra-Printer-Samples/tree/WeChat-MiniProgram-Samples

    要查询打印机上是否启用了蓝牙LE,请在Zebra设置实用程序ZSU中, 使用以下Zebra SGD命令:

    U1 getvarbluetooth.le.controller_mode

    要在打印机上启用Bluetooth LE,请使用以下Zebra SGD命令之一来通过Zebra设置实用程序在打印机上启用BLE:

    ! U1 setvar "bluetooth.le.controller_mode" "le"

    ! U1 setvar "bluetooth.le.controller_mode" "both"

    Services on Zebra printers

    斑马打印机上的蓝牙LE服务

    斑马打印机在蓝牙LE上提供了两种服务:一种是DIS服务(Device Information Service, UUID: `0x180A`),另一种是解析服务(Parser Service, UUID: `38eb4a80-c570-11e3-9507-0002a5d5c51b`)。这两种服务只能在蓝牙LE连接上以后,才能被发现。

    DIS是一种蓝牙的标准服务。中央设备(Central Devices)可以从DIS服务中读回打印机的设备名称、序列号、固件版本等特征值。解析服务是斑马打印机特有的服务,该服务包含两种特征值:从打印机读数据(`"From Printer Data"`)和向打印机写数据(`"To Printer Data"`)。

    斑马打印机蓝牙LE服务和特征值的UUID,都已经由[Link-OS Environment Bluetooth Low Energy AppNote](https://www.zebra.com/content/dam/zebra/software/en/application-notes/AppNote-BlueToothLE-v4.pdf)文档定义好了,如下面所示:

    // Zebra Bluetooth LE services and characteristics UUIDsconst ZPRINTER_DIS_SERVICE_UUID = "0000180A-0000-1000-8000-00805F9B34FB" // Or "180A". Device Information Services UUIDconst ZPRINTER_SERVICE_UUID="38EB4A80-C570-11E3-9507-0002A5D5C51B"       // Zebra Bluetooth LE Parser Serviceconst READ_FROM_ZPRINTER_CHARACTERISTIC_UUID = "38EB4A81-C570-11E3-9507-0002A5D5C51B" // Read from printer characteristicconst WRITE_TO_ZPRINTER_CHARACTERISTIC_UUID  = "38EB4A82-C570-11E3-9507-0002A5D5C51B" // Write to printer characteristic

    Write to characteristic

    每次对特征操作的写入都限制为BLE中的字节数。我们需要将ZPL或图像数据分成小块,并一次向特征写入一个字节块。在iOS上,一个接一个地写每个块时,wx.writeBLECharacteristicValue()没有问题。但是,在Android上,我们必须在写入块之间提供延迟。以下代码说明了如何将ZPL或图像数据分成多个块,以及如何为Android实现延迟。应该调整maxChunk和setTimeout()中的延迟以适合特定的Android设备和性能。当前,每次写入的延迟为250ms。

     // Write printer language string to the printerwriteStringToPrinter: function (str) {var that = thisvar maxChunk = 20 // Default is 20 bytes per write to characteristicif (app.getPlatform() == 'ios') {maxChunk = 300 // 300 bytes per write to characteristic works for iOS} else if (app.getPlatform() == 'android') {var maxChunk = 300 // Adjusting for Android      }if (str.length <= maxChunk) {writeStrToCharacteristic(str)} else {// Need to partion the string and write one chunk at a time.var j = 0for (var i = 0; i < str.length; i += maxChunk) {if (i + maxChunk <= str.length) {var subStr = str.substring(i, i + maxChunk)} else {var subStr = str.substring(i, str.length)}if (app.getPlatform() == 'ios') {writeStrToCharacteristic(subStr) // iOS doesn't need the delay during each write} else {// Android needs delay during each write.setTimeout(writeStrToCharacteristic, 250 * j, subStr) // Adjust the delay if neededj++}}}function writeStrToCharacteristic (str) {// Convert str to ArrayBuff and write to printerlet buffer = new ArrayBuffer(str.length)let dataView = new DataView(buffer)for (var i = 0; i < str.length; i++) {dataView.setUint8(i, str.charAt(i).charCodeAt())}// Write buffer to printerwx.writeBLECharacteristicValue({deviceId: that.data.connectedDeviceId,serviceId: ZPRINTER_SERVICE_UUID,characteristicId: WRITE_TO_ZPRINTER_CHARACTERISTIC_UUID,value: buffer,success: function (res) {wx.showToast({title: 'Sent ZPL to printer successfully',icon: 'success',duration: 1000,})},fail: function (res) {console.log("ssi - Failed to send ZPL to printer:", res)wx.showToast({title: 'Failed to send ZPL',icon: 'none',duration: 1000,})}})}},

    此外还可以进行截图,图片打印等功能

    Demo 软件运行参考图

    29b050f680618fa21ce068b148afe889.png

    参照了如下文献:

    * 斑马:[Link-OS Environment Bluetooth Low Energy AppNote](https://www.zebra.com/content/dam/zebra/software/en/application-notes/AppNote-BlueToothLE-v4.pdf)

    * 腾讯:[微信小程序软件开发环境和工具](https://mp.weixin.qq.com/)

    展开全文
  • 将一些调用复制在一起以便于输入.也许它是TEXT_ANTIALIASING,但我不会排除其他人.另一个想法是,某个地方的屏幕分辨率会缩放到打印分辨率;一个小的Java应用程序与自己动手打印将显示.你没有做旋转,是吗? (只是看到...

    你可以试试setRenderingHint;将一些调用复制在一起以便于输入.

    也许它是TEXT_ANTIALIASING,但我不会排除其他人.

    另一个想法是,某个地方的屏幕分辨率会缩放到打印分辨率;一个小的Java应用程序与自己动手打印将显示.

    你没有做旋转,是吗? (只是看到照片).

    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {

    Graphics2D g = (Graphics2D) graphics;

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT);

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);

    g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT);

    g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

    g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);

    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT);

    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);

    g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

    g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);

    return Printable.PAGE_EXISTS;

    }

    展开全文
  • Linux系统调用FAQ

    2013-04-19 14:08:00
    系统调用是操作系统为用户态运行的进程与系统内核、硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口,在应用程序和硬件之间设置一个额外层的优点包括: 1. 用户编程更加简单,不必学习硬件设备的低级编程...

    1. Linux系统调用的作用?

    系统调用是操作系统为用户态运行的进程与系统内核、硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口,在应用程序和硬件之间设置一个额外层的优点包括:

    1.         用户编程更加简单,不必学习硬件设备的低级编程特性;

    2.         提高了系统的安全性,内核在试图满足某个请求前在接口级可以检查请求正确性。

    3.         这组接口使得程序具有可移植性,只要内核所提供的接口相同,使用这些接口的        程序即可正确的编译和执行。

    2. POSIX API与系统调用的关系?

    1.         API是函数定义(如libc库),而系统调用是通过软中断想内核态发出的请求;

    2.         一个API没有必要对应一个特定的系统调用。API可能直接提供用户态服务,如数学函数;有些API函数可能调用几个系统调用;几个API函数可能调用同一系统调用(如malloccallocfree均使用brk系统调用实现)。

    3.         POSIX标准针对API而不是针对系统调用,判断一个系统是否与POSIX兼容,要看它是否提供了一组合适的API

    4.         从应用程序设计者的角度看,两者的差别仅在于名字、参数、返回值的不同;从内核设计者的角度看,系统调用属于内核,而API不属于内核。

     

    3. 内核如何处理系统调用?

    1.         每一个系统调用拥有一个系统调用号的标识,当用户态请求系统调用时,需传递系统调用号及其它信息作为参数,eax寄存器用于传递系统调用号(同时也用于传递返回值,系统调用号与返回值类型相同)。内核从寄存器读到系统调用的参数,并执行对应的系统调用服务例程。

    2.         下图显示了应用程序、相应的封装例程、系统调用处理程序、系统调用服务例程之间的关系。xyz()是应用程序的调用接口,xyzlibc中的调用实现通过调用SYSCALL汇编指令实现,该指令使得CPU切换到内核态(SYSEXIT反之);内核态通过sys_call系统调用处理程序来最终调用xyz的服务例程sys_xyz()

       20196318_128999749511Up.jpg

    3.         为了将系统调用号与相应的服务例程关联起来,内核利用一个系统调用分派表,该表存放在sys_call_table数组中,有NR_syscalls个表项,第n个表项包含系统调用号为n的服务例程的地址。

     

     

    4. 如何进入和退出系统调用?

    本地应用可以通过两种方式调用系统调用:

    1.         执行int $0x80汇编语言指令(老版本linux中从用户态切换到内核态的唯一方式)

    2.         执行sysenter汇编语言指令,Intel Pentium II微处理器引入该指令,linux2.6内核支持这条指令。

    同样,内核可通过两种方式从系统调用退出,使CPU切换回到用户态:

    1.         执行iret汇编语言指令

    2.         执行sysexit汇编语言指令

    对以上两种方式涉及到汇编代码,我也解释不太清楚,更详细的了解,请参考《深入理解linux内核》。

     

    5. 系统调用参数如何传递?

    1.         普通C函数的参数传递是通过把参数值写入到活动的程序栈(用户态或内核态堆栈)实现的,而系统调用同时跨越内核态和用户态,同时操作两个栈是很复杂的,而采用下面的方式(寄存器传递参数)将使得系统调用处理程序与其它异常处理程序的结构类似。

    2.         在发出系统调用之前,系统调用的参数被写入到CPU的寄存器,然后在调用系统服务例程之前,内核再把存放在CPU中的参数拷贝到内核态堆栈(系统调用服务例程是普通的C函数)。

    3.         使用寄存器传递参数必须满足:每个参数的长度不能超过寄存器的长度(容易解决,长度不够,可以通过传递参数的地址解决),并且参数的个数不能超过6个(系统调用号除外),因为80x86处理器的寄存器的数量是有限的(用于存放调用号和调用参数的寄存器是eaxebxecxedxesiediebp)。

     

    6. 如何保证系统调用的安全性?

    内核在满足用户的系统调用请求前,必须仔细的检查所有的系统调用参数,如write系统调用的参数fd,内核需检查fd是否对应于一个打开的文件,该文件是否允许写操作等,这些检查操作依赖于系统调用本身,也依赖于特定的参数。但有一种检查对所有的系统调用是通用的,只要参数指定的是地址,内核必须检查它是否属于用户地址空间,可通过检查地址所在的线性区,或直接与PAGE_OFFSET对比等两种方式实现(linux2.2开始实现第二种方式)。

     

    7. 内核如何访问用户态数据?

    系统调用服务例程需要非常频繁的读写进程地址空间的数据,Linux提供一组宏来实现这个目的(__开头的宏不包含对线性地址的有效性检查)。

    get_user  __get_user   从用户空间读一个整数(124个字节)

    put_user  __put_user   向用户空间写一个整数(124个字节)

    copy_from_user __copy_from_user  从用户空间复制任意大小的块

    copy_to_user  __copy_to_user  把任意大小的块复制到用户空间

    strncpy_from_user  __strncpy_from_user  从用户空间复制一个以null结束的字符串

    strlen_user  strnlen_user  返回用户空间以null结束的字符串的长度

    clear_user __clear_user 0填充用户空间的一个内存区域

     

    8. 在内核态能否调用系统调用?

    尽管系统调用主要由内核态进程使用,但也可以被内核线程调用,内核线程不能使用库函数。linux定义了7个从_syscall0_syscall6的一组宏来封装相应例程,宏名中的数字0-6对应着系统调用所用的参数个数(系统调用号除外)。每个宏需要2 + 2 * n个参数(n为系统调用参数的个数),前两个参数是系统调用号返回值类型和名字;每一对附加参数指明相应的系统调用参数的类型和名字。

    转载于:https://www.cnblogs.com/yunnotes/archive/2013/04/19/3032426.html

    展开全文
  • 2.8 Linux系统调用

    2017-10-13 10:36:50
    1、概述系统调用是操作系统为在用户态运行的进程与硬件设备(如打印机和磁盘)进行交互提供的一组接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,例如用户可以通过文件系统相关的调用请求...

    1、概述

    系统调用是操作系统为在用户态运行的进程与硬件设备(如打印机和磁盘)进行交互提供的一组接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,例如用户可以通过文件系统相关的调用请求系统打开文件和关闭文件等。

    系统调用的主要功能是使用户可以使用操作系统提供的有关设备管理、文件系统、进程控制、进程通讯以及存储管理方面的功能,而不必要了解操作系统的内部结构和有关硬件的细节问题,从而减轻用户负担和保护系统以及提高资源利用率。

    系统调用的执行让用户程序从用户态切换到内核态,该切换动作由一条软中断指令或一条类似的指令完成,在用户态执行完系统提供的服务程序后切换回用户态,继续执行用户态程序。

    1

    2、X86切换到内核态的两种指令

    本文只讲x86架构系统调用的实现。在x86架构中,由用户态切换到内核态有两种方法:一是通过软中断指令(int 0x80)实现;而是使用最新专有的系统调用指令sysenter/sysexit来实现的。Sysenter相对int 0x80做了优化,性能上有了成倍的增加。

    下面是一些有关 sysenter/sysexit 指令和 INT n/IRET 指令在 Intel Pentium CPU 上的性能对比:

    2

    • sysenter/sysexit 指令优化的详细说明:

    在 Linux 2.4 内核中,用户态 Ring3 代码请求内核态 Ring0 代码完成某些功能是通过系统调用完成的,而系统调用的是通过软中断指令(int 0x80)实现的。在 x86 保护模式中,处理 INT 中断指令时,CPU 首先从中断描述表 IDT 取出对应的门描述符,判断门描述符的种类,然后检查门描述符的级别 DPL 和 INT 指令调用者的级别 CPL,当 CPL<=DPL 也就是说 INT 调用者级别高于描述符指定级别时,才能成功调用,最后再根据描述符的内容,进行压栈、跳转、权限级别提升。内核代码执行完毕之后,调用 IRET 指令返回,IRET 指令恢复用户栈,并跳转会低级别的代码。

    其实,在发生系统调用,由 Ring3 进入 Ring0 的这个过程浪费了不少的 CPU 周期,例如,系统调用必然需要由 Ring3 进入 Ring0(由内核调用 INT 指令的方式除外,这多半属于 Hacker 的内核模块所为),权限提升之前和之后的级别是固定的,CPL 肯定是 3,而 INT 80 的 DPL 肯定也是 3,这样 CPU 检查门描述符的 DPL 和调用者的 CPL 就是完全没必要。正是由于如此,Intel x86 CPU 从 PII 300(Family 6,Model 3,Stepping 3)之后,开始支持新的系统调用指令 sysenter/sysexit。sysenter 指令用于由 Ring3 进入 Ring0,SYSEXIT 指令用于由 Ring0 返回 Ring3。由于没有特权级别检查的处理,也没有压栈的操作,所以执行速度比 INT n/IRET 快了不少。

    AMD 的 CPU 支持一套与之对应的指令 SYSCALL/SYSRET。在纯 32 位的 AMD CPU 上,还没有支持 sysenter 指令,而在 AMD 推出的 AMD64 系列 CPU 上,处于某些模式的情况下,CPU 能够支持 sysenter/sysexit 指令。在 Linux 内核针对 AMD64 架构的代码中,采用的还是 SYSCALL/SYSRET 指令。至于这两种指令最终谁将成为标准,目前还无法得出结论。

    值得一提的是,从 Windows XP 开始,Windows 的系统调用方式也从软中断 int 0x2e 转换到采用 sysenter 方式,由于完全不再支持 int 方式,因此 Windows XP 的对 CPU 的最低配置要求是 PentiumII 300MHz。

    3、内核态的实现

    操作系统提供的系统调用服务程序叫做system call service routine。一般你在用户态调用一个xxx()的系统服务,在内核态就有一个对应的sys_xxx()函数,该命名规则不是绝对的。内核态将所有的sys_xxx()函数指针组成一张表,然后会根据具体的系统调用号来查找使用这张表。
    Linux内核中系统调用服务表叫做sys_call_table,定义在arch/i386/kernel/syscall_table.S中:

    3

    每一个系统调用服务函数,还有一个对应的系统调用号,和这个函数指针表一一对应,其在Include/asm-i386/unistd.h文件中定义:

    4

    3.1、Int 0x80模式

    “Int 0x80”是软中断,该软中断的中断服务程序是system_call,定义在arch/i386/kernel/entry.S中:

    5

    既然是中断,还有中断向量的初始化,在arch/i386/kernel/traps.c的trap_init()中初始化Int 0x80的中断向量:

    6

    3.2、sysenter/sysexit模式

    sysenter/sysexit模式的内核服务程序是sysenter_entry,定义在arch/i386/kernel/entry.S中:

    7

    4、用户态(glibc) 的实现

    对用户态来说,一般不会使用“int 0x80”来直接调用内核态的系统调用,glibc函数把晦涩“int 0x80”指令包装起来,用户态程序调用的是glibc提供的api函数。
    所以研究系统调用用户态的实现看glibc的实现即可。

    4.1、只支持Int 0x80模式

    在linux 2.4内核只采用int 0x80的系统调用方式,所以对应的glibc库也支持采用int 0x80的方式。这种情况下,glibc中定义了_syscall0 ~ _syscall6一共7个不同参数个数的宏以供定义用户态的系统调用函数使用。
    在Include/asm-i386/unistd.h文件中,可以见到这些宏的定义:

    8

    _syscall0 ~ _syscall6宏,使用了gcc嵌入式汇编的方式,在c语言中调用汇编语句“int 0x80”进行系统调用。嵌入式汇编的一般形式是:asm volatile (“” : output : input : modify);具体的gcc嵌入式汇编的格式可以参见参考资料。

    举例,Glibc库中用户态的系统函数调用可以封装成:

    Int xxx(int arg1,int arg2)
    {
       Int ret =0 ;
    
      Ret = _syscall2(int, xxx, int, arg1, int, arg2) ;
    
          Return (ret) ;
    }

    同时要保证内核中有相应的服务程序sys_xxx(),Include/asm-i386/unistd.h文件中有对应__NR_xxx系统调用号的定义。

    4.2、兼容Int 0x80和sysenter/sysexit模式

    在linux 2.6内核中加入对sysenter/sysexit模式的支持,同时支持Int 0x80和sysenter/sysexit模式的系统调用。

    虽然sysenter/sysexit模式的效率高,但是并不是所有的CPU都支持该特性,老的CPU没有此特性。为了实现用户代码接口的统一,设计了一种新的机制:内核态提供给用户态一段通用代码,内核启动时根据 CPU 类型,决定这段代码采取哪种系统调用方式,对于用户态glibc 来说,无需考虑系统调用方式,直接调用这段入口代码,即可完成系统调用。这种方式可以叫做vsyscall模式。

    前面说到内核态需要提供给用户态一段通用代码,这段代码的大小为1页内存,地址在0xffffe000开始到0xffffefff,称为vsyscall页。页中的内容是内核在启动时根据cpu的sysenter/sysexit能力,选择把int 80h模式的vsyscall代码或者sysenter模式的vsyscall代码复制到0xffffe000页中。

    地址0xffffe000是属于内核虚地址空间,但是这部分的内核地址用户态是可以访问的。而且在使用ldd查看用户可执行程序的库依赖关系时,这段vsyscall代码被看成一个虚拟的库linux-gate.so.1。

    9

    int 80h模式的vsyscall代码,在arch/i386/kernel/ vsyscall_int80.S中:

    10

    sysenter模式的vsyscall代码,在arch/i386/kernel/vsyscall_sysenter.S中:

    11

    arch/i386/kernel/vsyscall-sysenter.S 和arch/i386/kernel/vsyscall-int80.S入口名都是 __kernel_vsyscall,这两个文件编译出的二进制代码由arch/i386/kernel/vsyscall.S所包含,并导出起始地址和 结束地址:

    12

    内核在启动时,调用sysenter_setup 函数设置vsyscall页,定义在arch/i386/kernel /sysenter.c:

    13

    配合vsyscall模式,新版本glibc中系统调用的宏是INLINE_SYSCALL,在sysdeps/unix/sysv/linux/i386/sysdep.h中定义:

    14

    举例,Glibc库中用户态的系统函数fork的实现:

    15

    4.3、内核和glibc的新旧版本兼容关系

    在支持系统调用的模式上:

    • Cpu:分为支持的和不支持sysenter指令的;
    • 内核 :分为原始模式的和 支持vsyscall模式的。两种模式对int 0x80指令都支持;vsysvall模式的内核需要配合vsyscall模式的库自动适配cpu的sysenter能力;
    • Glibc库:分为int 80模式的和使用vsyscall模式。int 80模式的库在两种内核下都可以执行;vsyscall模式的库需要配合vsyscall模式的内核才能正常使用sysenter,否则使用int 80方法。

    5、32位程序在64位内核的系统调用

    16

    64位内核的系统调用关系图
    由上图可见,在32位应用程序运行在64位的内核上,其调用路径为左边黄色色箭头部分,而64位应用程序的系统调用走的是右边绿色箭头。
    所以在32位应用程序的系统调用就必须考虑在 Ia32entry.S中是否有对应的系统调用入口,从目前的代码分析看,只有ioctl接口有差别,其他的接口需要再深入排查。
    可以查看arch/x86_64/kernel/entry.S和arch/x86_64/ia32/ia32entry.S中的实际代码。感兴趣自己再研究一下64位系统下的系统调用机制。

    6、举例:增加一条自己的系统调用

    • 1、在内核代码中增加自己函数,并编译进内核:
    asmlinkage int sys_mysyscall(void)
    {
            current->uid = current->euid = current->suid = current->fsuid = 0;
            return 0;
    }  
    • 2、在arch/i386/kernel/syscall_table.S中增加自己调用入口:
    .long sys_mysyscall
    • 3、在Include/asm-i386/unistd.h文件中增加自己的系统调用号,并修改NR_syscalls:
    #define __NR_ mysyscall     xxx
    
    #define NR_syscalls (xxx+1)
    • 4、重新编译内核

    • 5、编写用户态程序,调用自己新增的系统调用:

    #include <linux/unistd.h>
    _syscall0(int,mysyscall)    /* 注意这里没有分号 */
    
    int main()
    {
    mysyscall();
    printf(“em…, this is my uid: %d. \n”, getuid());
    }

    7、参考资料

    展开全文
  • 第10章 系统调用接口 系统调用接口的功能 内核为用户与硬件设备(例如CPU磁盘打印机等)交互提供了一个接口该接口被称为系统调用接口它的功能是 使用户编程更加容易把用户从学习硬件设备的低级编程特性中解放出来 可以...
  • 首先,要说一下两者的概念: 系统调用:是操作系统为用户态运行的进程和硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口,即就是设置在应用程序和硬件设备之间的一个接口层。可以说是操作系统留给用户程序的...
  • 1) 操作系统为用户态的进程与硬件设备(如CPU、磁盘和打印机等)之间的交互提供了一组接口,这些接口使得程序更具有可移植性,因为不同的操作系统只要所提供的一组接口相同,那么在这些操作系统之上就可
  • LinuxLinux系统简介

    2021-02-22 10:00:08
    我们的 Linux 主要是系统调用和内核那两层。当然直观地看,我们使用的操作系统还包含一些在其上运行的应用程序,比如文本编辑器、浏览器、电子邮件等。 Linux 历史简介 操作系统始于二十世纪五十年代,当时的操作...
  • linux简单了解

    2020-09-18 19:56:58
    linux主要是系统调用和内核那两层。直观的看,我们使用的操作系统海报口一些在其上运行的应用程序,如文本编辑器,浏览器,电子邮件 linux历史过程 操作系统始于20世纪50年代,当时操作系统运行的是批处理程序。它不...
  • 库函数和系统调用

    2016-09-29 21:18:37
    系统调用(system call):是操作系统为用户态运行的进程和硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口,即就是设置在应用程序和硬件设备之间的一个接口层。可以说是操作系统留给用户程序的一个接口。再...
  • 系统调用与库函数

    2016-05-01 22:36:34
    是操作系统为用户态运行的进程和硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口,即就是设置在应用程序和硬件设备之间的一个接口层。可以说是操作系统留给用户程序的一个接口。再来说一下,linux内核是单...
  • 内核是系统的“心脏”,是运行程序和管理像磁盘和打印机等硬件设备的核心程序,它提供了一个在裸设备与应用程序间的抽象层。 内核是操作系统的核心,具有很多最基本的功能,如虚拟内存,多任务,共享库,需求加载,...
  • linux内核

    2007-09-26 18:23:00
    Linux内核 内核是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序。它从用户那里接受命令并把命令送给内核去执行。内核是操作系统的内部核心程序,它向外部提供了对计算机设备的核心管理调用。我们...
  • 库函数与系统调用的区别

    千次阅读 2016-12-23 21:36:13
    通过系统调用,可以使得用户态运行的进程与硬件设备(如CPU、磁盘、打印机等)进行交互,是操作系统留给应用程序的一个接口。下面适用于访问设备驱动程序的系统调用: open: 打开文件或设备 read: 从打开的文件或
  • 00 Linux内核及发行版 linux内核版本 ...是包含了linux内核的,通过linux内核的系统调用可以直接访问硬件,而不一定需要终端程序。通常包含了包括桌面环境、办公套件、媒体播放器、数据库等应用软...
  • 我在Linux上做了软件,当我在linux上连接打印机时,打印机工作得很好 . 但是当我在Windows上连接打印机时,它无法正常工作 . 我的驱动程序很好,我知道因为我可以打印测试页,但是当我要去软件时,打印机不能工作 ....
  • 通过系统调用,可以使得用户态运行的进程与硬件设备(如CPU、磁盘、打印机等)进行交互,是操作系统留给应用程序的一个接口。下面适用于访问设备驱动程序的系统调用: open: 打开文件或设备  read: 从打开的文件或...
  • 系统调用:是操作系统为用户态运行的进程和硬件设备(如CPU、磁盘、打印机等)进行交互提供的一组接口,即就是设置在应用程序和硬件设备之间的一个接口层。可以说是操作系统留给用户程序的一个接口。再来说一下,linux...
  • Linux 就是一个操作系统,Linux 也就是系统调用和内核那两层。 二、Linux 历史简介 操作系统始于二十世纪 50 年代,当时的操作系统能运行批处理程序。批处理程序不需要用户的交互,它从文件或者穿孔...
  • 这就意味着,通常程序可以像使用文件那样使用磁盘文件、串行口、打印机和其他设备。 在输入输出操作中,直接使用底层系统调用的问题使它们的效率非常低。为什么呢? 系统调用会影响系统的性能。与函数调用相比,...
  • 实际上,用户是不用接触操作系统的,操作系统管理着计算机硬件资源,同时按照应用程序的资源请求,分配资源,如:划分CPU时间,内存空间的开辟,调用打印机等。那么操作系统的结构是什么样的呢?下面我给大家一幅图...
  • linux的俩个版本

    2020-02-19 21:12:21
    内核:是系统的心脏,是管理运行程序和管理如磁盘、打印机一类的硬件设备的核心程序。并且有俩个重要的组成部分,终端命令和系统调用。 2、linux发行版 在内核内搭建另一个运行程序,也就是说发行版包括内核版。 这...
  • 1 Linux io文件操作总结

    2015-05-11 20:26:40
    这就意味着,普通程序完全可以像使用文件(普通定义)那样使用磁盘文件、串行口、打印机和其他设备 3. 库函数调用最终也是通过系统调用实现的。可认为库函数调用是对系统调出于效率考虑而做出的优化。 ...
  • 最近在用freeswitch软交换进行语音通话,通话的时候需要调用音频文件进行播放,当并发量上来的时候,freeswitch监听服务的端口会不断的down掉,查看日志发现报了一个错如下:这个问题经常在Linux上出现,而且常见于...
  • Linux之操作系统杂谈

    2020-03-12 23:02:50
    通过系统调用,可以使得用户态运行的进程与硬件设备(如CPU、磁盘、打印机等)进行交互,是操作系统留给应用程序的一个接口。 标准库函数:库函数调用则是面向应用开发的,库函数可分为两类,一类是C语言标准规定的...
  • 国产服务器 国产麒麟客户机 火狐浏览器 JAVA开发的b/s架构程序 SDK 解释一下sdk是什么,sdk定义很广不用可以理解,调试过程中会慢慢理解,主要职责是提供第三方调用本服务的一个入口,比如图书管理系统和教务管理...

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

linux程序调用打印机

linux 订阅