创建设备文件节点mknod

装载驱动程序后,如主设备号为248,则创建设备为

mknod /dev/chardev c 248 0

参数说明: c 为char device 字符设备的意思,248为主设备号,0为次设备号

error: function declaration isn’t a prototype

/usr/src/program/procfs1.c:31:6: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 void create_new_proc_entry(){

参考:https://stackoverflow.com/questions/42125/function-declaration-isnt-a-prototype

In C int foo() and int foo(void) are different functions. int foo() accepts an arbitrary number of arguments, while int foo(void) accepts 0 arguments. In C++ they mean the same thing. I suggest that you use void consistently when you mean no arguments.

If you have a variable a, extern int a; is a way to tell the compiler that a is a symbol that might be present in a different translation unit (C compiler speak for source file), don’t resolve it until link time. On the other hand, symbols which are function names are anyway resolved at link time. The meaning of a storage class specifier on a function (extern, static) only affects its visibility and extern is the default, so extern is actually unnecessary.

I suggest removing the extern, it is extraneous and is usually omitted.

.read 格式

/usr/src/program/procfs1.c:15:11: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
   .read = procfile_read,

格式定义为 :

ssize_t
read_proc(struct file *filp,
      char __user *buf,
      size_t count,
      loff_t *offp){

https://courses.cs.washington.edu/courses/cse451/10au/tutorials/tutorial_ctags.html

Ctags Tutorial






Ctags is a tool that makes it easy to navigate large source code projects. It provides some of the features that you may be used to using in Eclipse or other IDEs, such as the ability to jump from the current source file to definitions of functions and structures in other files. Ctags will make it much easier to find the Linux kernel files that you have to modify for your CSE 451 projects. Ctags also supports many languages besides C, so you may find it useful for future projects.

Ctags should already be installed on CSE instructional servers such as forkbomb and attu. Ctags is first run on its own to generate a “tags” file, then it is invoked from within another Linux text editor such as Emacs or Vim.

These steps assume you want to use Ctags on the Linux kernel, but should generalize to other projects.

Important

If you are not on forkbomb or attu, make sure that the system you are using has “Exuberant Ctags” installed, rather than the original “Ctags,” by running ctags --version.

Tip

Like all Linux programs, Ctags has a man page (man 1 ctags). All of the information in this tutorial, and lots more advanced information, can be found there.

<

div class=”section” id=”ctags-with-emacs”>

Ctags with Emacs

Tip

If you are unfamiliar with Emacs, you should go through the Emacs tutorial. Run emacs, then press C-h t (Ctrl+h, then t) to begin the interactive tutorial. It shouldn’t take too long, and it’s worth your time. You can also check out the online tour. If you get stuck, press C-g to cancel pending commands, and exit Emacs by pressing C-x C-c.

Disclaimer

The author of this tutorial is not an Emacs expert; if you notice potential flaws or improvements, please contact him.

<

ol class=”arabic”>

  • cd to the root directory of your Linux kernel code:

    cd /cse451/user/project1/linux-2.6.13.2/
    
  • Run Etags (Ctags for Emacs) over the kernel to generate the TAGS file. etags will overflow its stack if called recursively over the entire kernel, so we use the find command to find all of the .c, .h, and .S (assembly) files in the kernel, then tell etags to append the tags in those files to the TAGS file. For Linux 2.6.13, this should only take a minute or so:

    find . -type f -iname "*.[chS]" | xargs etags -a
    

    Note

    You may see messages like “Warning: cannot open source file ‘…’ : Permission denied” while etags is building the tags file. These warnings can be ignored.

  • Open any Linux source file in Emacs and use the following basic commands:

    Keyboard command

    Action

    M-. <RET>

    Jump to the tag underneath the cursor

    M-. <tag> <RET>

    Search for a particular tag

    C-u M-.

    Find the next definition for the last tag

    M-*

    Pop back to where you previously invoked “M-.”

    Important

    The first time you run an Etags command within Emacs, you may have to specify the location of your TAGS file (i.e. /cse451/.../linux-2.6.13.2/TAGS). Say yes when prompted to load the really big tags file.

    The first command is probably the one you will use most often: it jumps to the definition of the tag (function name, structure name, variable name, or pretty much anything). The second command can be used to search for any tag in the TAGS file, regardless of the file you are currently viewing. Sometimes Etags will find multiple definitions for a given tag; when this is the case, use the third command to jump through the possible definitions until you find the one that you want. Finally, use the fourth command to jump back up in the tag “stack.”

    You’ll probably find that for some tags (common structures, for example), Etags finds hundreds or thousands of uses in the code, and jumping through them (with the third command above) to try to find the original definition is useless. In this case, you can run the following two commands to list all of the uses of a given <tag>:

    M-x tags-apropos <RET>
    Tags apropos (regexp): <tag> <RET>
    

    This will display a list of the tag definitions in another buffer. Switch to the new buffer (C-x o), scroll through the list of definitions to the one that you want, then press Enter to open the file. When you’re done, instead of jumping back up in the tag stack, close the new buffer (C-x k). To switch back to your original buffer and expand it, use C-x o to switch to it, then C-x 1 to expand.

    <

    div class=”note”>

    Note

    <

    p class=”last”>Even the list of all definitions given by tags-apropos may be too large to find the definition that you’re looking for. This is mostly a problem for structs (struct inode, for instance) that are used frequently in the kernel. You should still find Etags useful for jumping to function definitions and less-commonly-used structs. Ctags for Vim appears to do a better job of separating “definitions” from “uses” in its tags file, so this is less of a problem for Vim; for Emacs, there may be other ways to mitigate this problem (see this page, for example). Alternatively, you may wish to use cscope to find function and structure definitions, or just use the third step of the Vim instructions below.

  • 树莓派+A6模块实现短信自动转发功能(短信网关)

    借鉴:
    https://xmsg.org/wordpress/2017/02/%E5%88%A9%E7%94%A8%E7%9F%AD%E4%BF%A1%E6%A8%A1%E5%9D%97%E9%85%8D%E5%90%88gammu%E5%AE%9E%E7%8E%B0%E7%94%A8%E7%9F%AD%E4%BF%A1%E7%AE%A1%E7%90%86linux%E6%9C%8D%E5%8A%A1%E5%99%A8/ 前人的足迹
    https://blog.csdn.net/ki1381/article/details/79690060 前人的足迹
    https://wammu.eu/docs/manual/ gammu官方手册

    0x00 目的

    有一个手机但是有两张卡,一张老卡,一张新卡,老卡随身带着或者再买个手机插上太麻烦,但是有些用老卡绑定的账户操作需要短信验证码,所以想将短信自动转发到新卡上
    还有一位群内大佬说怕被定位,这样的话还要实现voip功能,不在此文范围内
    此文只是抛砖引玉,如果转发短信贵的话,其实还可以配置自动发送到微信,或者用手机远控/监听之类的功能,也不在此文范围内,请根据文档自由发挥

    0x01 材料

    树莓派+A6模块+手机卡(关闭开机PIN码)(+usb-tty)

    A6模块天线一定要买好的,这里A6使用单独数据线5V供电,是因为树莓派5V供电不稳定

    线的接法应该是Tx1-Rx2 Tx2-Rx1但是这里用了usb转tty,所以应该是T-T R-R的接法(A6模块接U开头的,U_Rx U_Tx)

    树莓派安装minicom(调试用)gammu(调试用)gammu-smsd(实战用)gammu-doc(应该包含数据库文件和文档,这里我们没有用到)

    apt-get install minicom gammu gammu-smsd mysql-server
    

    这里注意一下所下载的gammu-smsd版本,树莓派基于debian所以版本为1.38.1,如果使用数据库的话需要对应版本的数据库文件,可以去github上下载

    0x02 调试模块

    树莓派3如果使用串口的话需要进行复杂的设置,具体看这:
    https://blog.csdn.net/ki1381/article/details/79690060
    我们这里直接使用usb转tty

    树莓派执行命令:

    ls /dev/ttyUSB*
    service gammu-smsd stop
    minicom -s
    

    显示minicom配置界面,
    选择serial port setup,想修改哪个就按前面对应的键(A-Z)
    修改串口设备为刚才找到的串口文件,这里假设是/dev/ttyUSB0
    ** 修改Hardware Flow Control为No,这里如果是YES将会出现无法写入问题 **
    然后执行

    minicom -D /dev/ttyUSB0
    

    热插拔一下A6电源,会有初始化输入显示,输入AT回车,回显OK表示正常,输入AT+COPS?
    ** 如果无法输入或卡死,很可能是gammu-smsd正在运行占用了设备,执行service gammu-smsd status查看状况 **
    如果类似+COPS:0,0,”UNICOM”说明卡片注册成功,失败的话请检查手机卡是否插反了(A6手机卡缺口朝外),是否是信号太弱,或者卡片自身问题
    调试成功后关闭minicom(CTRL+A X)
    执行gammu-config
    依然是设置所选设备,串口通信率为at115200,保存。这样当前目录下会生成一个.gammurc配置文件
    执行gammu –identify,如果回显芯片的具体信息说明成功

    然后发条短信测试一下:

    gammu sendsms TEXT 要接收短信的手机号码 -text "123"
    

    收到123表示成功,接下来配置gammu-smsd

    0x03 gammu-smsd的配置

    首先我们运行mysql,根据官方文档内容建立数据库和用户

    GRANT USAGE ON *.* TO 'smsd'@'localhost' IDENTIFIED BY '要设置的密码';
    
    GRANT SELECT, INSERT, UPDATE, DELETE ON `smsd`.* TO 'smsd'@'localhost';
    
    CREATE DATABASE smsd;
    

    然后导入所下载的mysql.sql文件,版本一定要对应

    mysql -u root smsd < mysql.sql
    

    这里不加密码是因为安装mysql后自动使用unix_socket进行连接(mysql.user表中的plugin属性)
    导入后编辑gammu-smsd配置文件/etc/gammu-smsdrc

    # Gammu library configuration, see gammurc(5)
    [gammu]
    # Please configure this!
    port = /dev/ttyUSB0
    model =
    connection = at115200
    # Debugging
    #logformat = textall
    
    # SMSD configuration, see gammu-smsdrc(5)
    [smsd
    ReceiveFrequency = 5 #5秒接收一次短信
    #PIN = 1234 有PIN码的写在这
    service = sql
    driver = native_mysql
    # Increase for debugging information
    User = smsd
    Password = 你建立的用户的密码
    PC = localhost
    Database = smsd
    
    # Paths where messages are stored
    inboxpath = /var/spool/gammu/inbox/
    outboxpath = /var/spool/gammu/outbox/
    sentsmspath = /var/spool/gammu/sent/
    errorsmspath = /var/spool/gammu/error/
    
    

    保存后启动

    service gammu-smsd start
    

    给A6上的卡号发送短信,5秒后进入mysql查看

    use smsd;
    select * from inbox;
    

    如果有记录说明成功,现在开始配置自动转发。

    0x04 自动转发的配置

    这里主要借鉴https://xmsg.org/wordpress/2017/02/%E5%88%A9%E7%94%A8%E7%9F%AD%E4%BF%A1%E6%A8%A1%E5%9D%97%E9%85%8D%E5%90%88gammu%E5%AE%9E%E7%8E%B0%E7%94%A8%E7%9F%AD%E4%BF%A1%E7%AE%A1%E7%90%86linux%E6%9C%8D%E5%8A%A1%E5%99%A8/ 前人的足迹

    通过官方文档,可以找到一条配置为RunOnReceive,此配置决定了当收到短信时执行的命令,这里我们建立一个有执行权限的sh文件

    touch /home/pi/smsrecv.sh
    chmod 755 /home/pi/smsrecv.sh
    

    然后在配置文件中[smsd]下写入

    RunOnReceive = /home/pi/smsrecv.sh
    

    这样每次收到短信自动执行此脚本
    脚本文件可以自己写,可以使用前人的写好的

    利用短信模块配合gammu实现用短信管理树莓派

    #!/bin/sh
    #code xmsg.org
    #20151015
    #20151018
    #20151019 1.0 正式版
    #20170204 从现在开始它将被修改成一个短信控制系统
    ############################################################
    #在本次SHELL中我还是学到了不少东西
    #一 在if条件中各项内容之间的空格必不可少,不然执行就会出错。
    #二 在一个逻辑块中(比如if块)中只有存在错误(比如我在执行脚
    #   本时最后少写一个反引号)会引起整个块不被执行。
    #三 初始化变量时变量名前一定不能加美元符号,在知道的情况下还
    #   是会犯这种错误。
    #四 虽然在脚本中使用空格分隔内容可以让内容更清晰,但初始化变
    #   量的情况下[变量 等于 数据]这个过程中等于号前号一定不能
    #   有空格。
    #五 需要eval要小心使用,它在强大的同时可能引起安全问题。
    ############################################################
    # !ip 获取本机的出口IP
    # !pt 获取本机开放的端口
    # !tcp 获取本机开放的TCP端口
    # !ssh 启动SSH
    # !sshoff 关闭SSH
    # !rt 重启系统
    # !so 清除转发
    # !so localport localnetip localnetport 设置内网对外转发
    
    #FULLMSG=$SMS_1_NUMBER
    #FULLMSG="$FULLMSG"#
    #手机号需要带国家代码,中国是+86
    NUMBER=$SMS_1_NUMBER
    #UNKNOWN ERROR
    NOTFOUND="Unknown Error"
    MASTERPHONE="你的手机号11位别搞错,别不写!"
    #############短信白名单###########################################
    #正式版需要有一个白名单这可以减少大量恶意攻击
    #
    ########################################################
    
    #echo FULLMSG >>;/tmp/all.log
    for i in `seq $SMS_MESSAGES` ; do
    #echo ---- >>/tmp/all.log
        varname="SMS_"$i"_TEXT"
        #echo $varname >>/tmp/all.log
        smspart=`eval echo '$'$varname`
        #echo $smspart >>/tmp/all.log
        FULLMSG="$FULLMSG$smspart"
    done
    #echo $FULLMSG >>/tmp/all.log
    
    # $NUMBER中存放了手机号码
    # $FULLMSG中存了完整短信内容
    
    #echo resend a sms from "$NUMBER" >>/tmp/debug.log
    #手机号中包含国家代码
    if [ "$NUMBER" != "+86$MASTERPHONE" ]; then
    #一般短信就转发给我自己吧。
            echo resend a sms "$FULLMSG".from."$NUMBER" >>/tmp/gate.log
            `eval "gammu-smsd-inject EMS $MASTERPHONE -unicode -text \"$FULLMSG.from.$NUMBER\""`
            exit 0
    fi
    
    if [ "$FULLMSG" = "!ip" ]; then
    #获取外网IP
            EVALRET=`curl -k https://xmsg.org/tool/ip.php`
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "$EVALRET"`
            exit 0
    elif [ "$FULLMSG" = "!pt" ]; then
    #获取本机端口
            EVALRET=`netstat -an|grep "^[tu].p .*0:\*.*"`
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "$EVALRET"`
            exit 0
    elif [ "$FULLMSG" = "!tcp" ]; then
    #获取本机端口
            EVALRET=`netstat -an|grep "^tcp .*0:\*.*"`
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "$EVALRET"`
            exit 0
    elif [ "$FULLMSG" = "!ssh" ]; then
    #启动SSH
            EVALRET=`sudo service ssh start`
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "ssh start"`
            exit 0
    elif [ "$FULLMSG" = "!sshoff" ]; then
    #关闭SSH
            EVALRET=`sudo service ssh stop`
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "ssh stop"`
            exit 0
    elif [ "$FULLMSG" = "!rt" ]; then
    #重启本机
            sudo reboot
            exit 0
    elif [ "$FULLMSG" = "!so" ]; then
    #清除转发
            sudo killall socat
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "socat killed"`
            exit 0;
    elif [ "`expr substr \"$FULLMSG\" 1 3`" = "so " ]; then
    #设置转发
            EVALRET=`eval "sudo /home/pi/bin/$FULLMSG"`
            #echo "sudo /home/pi/bin/$FULLMSG">>/tmp/a.log
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "$EVALRET"`
            exit 0;
    else
            #echo `expr substr "$FULLMSG" 1 3` >>/tmp/a.log
            #echo "sudo /home/pi/bin/$FULLMSG">>/tmp/a.log
            EVALRET=`eval "$FULLMSG"`
            `gammu-smsd-inject EMS $MASTERPHONE -unicode -text "$EVALRET"`
            echo "$FULLMSG" >> /tmp/gate.log
            echo "$EVALRET" >> /tmp/gate.log
            exit 0
    fi
    exit 0
    

    安装socat创建文件so

    #!/bin/sh
    if [ $# -eq 3 ]; then
            RET=`/usr/bin/socat TCP4-LISTEN:$1,reuseaddr,fork TCP4:$2:$3 >/dev/null 2>&1 &`
            echo "$2:$3->$1"
    elif [ $# -eq 2 ]; then
            RET=`/usr/bin/socat TCP4-LISTEN:$1,reuseaddr,fork TCP4:$2:$1 >/dev/null 2>&1 &`
            echo "$2:$1->$1"
    else
            echo args error
    fi
    

    然后修改完配置文件需要重启服务

    service gammu-smsd restart
    

    重启后随便找个验证码注册或找回的网站,或者使用其他手机发送上面脚本文件定义的的指令到这张卡上” alt=”” width=”750″ height=”1334″ class=”alignnone size-full wp-image-246″ />
    至此短信网关搭建成功

    内存卡连接电脑,打开boot分区,新建wpa_supplicant.conf

    country=CN
    ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
    update_config=1
    
    network={
    ssid="WiFi-A"
    psk="12345678"
    key_mgmt=WPA-PSK
    priority=1
    }
    
    network={
    ssid="WiFi-B"
    psk="12345678"
    key_mgmt=WPA-PSK
    priority=2
    scan_ssid=1
    }
    

    建立空文件ssh即可开机开启ssh

    打开/etc/network/interfaces

    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    
    # The loopback network interface
    auto lo
    iface lo inet loopback
    
    # The primary network interface
    allow-hotplug eth0
    auto eth0
    iface eth0 inet static
    address 192.168.1.199
    netmask 255.255.255.0
    gatway 192.168.1.1
    ~                                                                                                             
    ~
    

    如果dhcp

    iface eth0 inet dhcp
    

    网关

    /etc/resolv.conf
    nameserver 192.168.1.1
    nameserver 0.0.0.0  
    /etc/init.d/networking restart
    

    失败,查看原因,找不到driver,eth0执行

    dmesg | grep eth 
    

    才发现

    [5.715564] e1000 0000:02:01.0 eth0: (PCI:66MHz:32-bit) 00:0c:29:7d:bf:43
    [5.715573] e1000 0000:02:01.0 eth0: Intel(R) PRO/1000 Network Connection
    [5.719709] e1000 0000:02:01.0 ens33: renamed from eth0
    

    所以改成ens33就行了