您的位置:首页 > 运维架构 > Linux

Linux驱动开发系列:2W字长文整理入门Ubuntu知识

2021-06-07 15:30 1271 查看

文章目录

  • 2.4 Ubuntu软件安装
  • 3.Ubuntu文件系统结构
  • 4.Ubuntu磁盘管理
  • 5.Ubuntu压缩与解压缩
  • 5.3 其他格式的压缩和解压缩
  • 6.Ubuntu用户与用户组
  • 7. 文件权限管理
  • 8.Ubuntu连接文件(Linux通用)
  • 9.Vim编辑器常用操作
  • 10.Linux下C编程入门
  • 11.make工具和Makefile文件
  • 12.Shell脚本入门基础
  • 以上就是做Linux驱动开发时需要的Ubuntu入门知识了,后期我还会更新Linux下IMX6ULL裸机开发的学习教程,欢迎大家点个关注和收藏哇!另外如果文章内容有错误的话,欢迎大家在评论区指正呀,如果你需要PDF版本的文章 20000 f0c;也欢迎留下邮箱哦!
  • Linux驱动开发

    Linux指令非常多,全部记忆基本不可能,所以总结文章只选取重要的指令进行总结,其具体的指令上Linux指令查询网:https://www.linuxcool.com/,进一步查询使用

    一、Linux驱动开发第一期:Ubuntu基础入门

    1.Vmware虚拟机安装

    参考教程:虚拟机VMware最详细下载与安装教程

    2.Vmware内Ubuntu功能介绍

    2.1 启动栏介绍

    启动栏介绍如图所示

    2.2 Ubuntu连接USB设备

    图形界面下两种连接方式

    1. 拔插选择设备连接

    2. Vmware右下角进行切换

    2.3 Ubuntu终端下Shell操作

    Ubuntu终端指命令行操作界面,打开终端后我们通过输入shell指令来进行操作,下面我们讲解一下常用Shell指令操作(所有Linux版本基本通用)

    2.3.1 Shell 基本操作

    Shell 命令的格式 如下:

    command -options [argument]

    command: Shell 命令名称。

    options:选项,同一种命令可能有不同的选项,不同的选项其实现的功能不同。

    argument:Shell 命令是可以带参数的,也可以不带参数运行。

    以ls为例,分别执行如下指令

    ls
    ls -l
    ls /usr

    执行结果如下

    ls命令用来打印出当前目录下的所有文件和文件夹

    ls -l同样是 打印出当前目录下的所有文件和文件夹,但是此命令会列出所有文件和文件夹的详细信息,比 如文件大小、拥有者、创建日期等等。

    ls /usr是用来打印出目录“/usr”下的所有 文件和文件夹。

    Shell 命令是支持自动补全功能的,要输入命令的前面一部分字 母,然后按下 TAB 键自动补全,如果有多个指令,可以选择全部列出

    以上为基本操作

    2.3.2 Shell 常用指令

    Shell 命令是所有的 Linux系统发行版所通用的,指令在所有版本linux下都通用

    • 目录信息查看命令 ls

    文件浏览是最基本的操作了,Shell 下文件浏览命令为 ls,格式如下

    ls [选项] [路径]

    主要参数有:

    -a 显示所有的文件以及子目录,包括以“.”开头的隐藏文件。

    -l 显示文件的详细信息,比如文件的形态、权限、所有者、大小等信息。

    -t 将文件按照创建时间排序列出。

    -A 和-a 一样,但是不列出“.”(当前目录)和“…”(父目录)。

    -R 递归列出所有文件,包括子目录中的文件。

    注意:Shell 命令里面的参数是可以组合在一起用的,比如组合“-al”就是显示所有文件的详细信 息,包括以“.”开头的隐藏文件

    • 目录切换命令 cd

    中切换到其它的目录,使用的命令是 cd,命令格式如下

    cd [路径]

    使用范例

    cd / 		//进入到根目录“/”下,Linux 系统的根目录为“/”,
    cd /usr		//进入到目录“/usr”里面。
    cd .. 		//进入到上一级目录。
    cd ~ 		//切换到当前用户主目录
    • 当前路径显示命令pwd

    pwd 命令用来显示当前工作目录的绝对路径,不需要任何的参数

    • 系统信息查看命令 uname

    查看当前系统信息

    uname [选项]

    可选的选项参数如下:

    -r 列出当前系统的具体内核版本号。

    -s 列出系统内核名称

    -o 列出系统信息

    • 清屏命令 clear

    clear 命令用于清除终端上的所有内容,只留下一行提示符(实际上未清除,只是推到最上面了)

    • 切换用户执行身份命令 sudo

    sudo 命令可以 使我们暂时将身份切换到 root 用户。当使用 sudo 命令的时候是需要输入密码的,这里要注意输 入密码的时候是没有任何提示的!

    sudo [选项] [命令]

    选项主要参数如下:

    -h 显示帮助信息。

    -l 列出当前用户可执行与不可执行的命令

    -p 改变询问密码的提示符。

    • 添加用户命令 adduser

    此命令需要 root 身份去运行。命令 格式如下:

    adduser [参数] [用户名]

    主要参数有:

    -system 添加一个系统用户

    -home DIR DIR 表示用户的主目录路径

    -uid ID ID 表示用户的 uid

    -ingroup GRP 表示用户所属的组名

    • 删除用户命令 deluser

    删除用户使用命令“deluser”,命 令参数如下:

    deluser [参数] [用户名]

    主要参数有:

    -system 当用户是一个系统用户的时候才能删除

    -remove-home 删除用户的主目录

    -remove-all-files 删除与用户有关的所有文件

    -backup 备份用户信息

    • 切换用户命令 su

    命令“su”可以 直接将当前用户切换为 root 用户,切换到 root 用户以后就可以尽情的进行任何操作了!因为你 已经获得了系统最高权限,在 root 用户下,所有的命令都可以无障碍执行,不需要在前面加上 “sudo”,“su”命令格式如下:

    su [选项] [用户名]

    常用选项参数如下:

    -c –command 执行指定的命令,执行完毕以后恢复原用户身份。

    -login 改变用户身份,同时改变工作目录和 PATH 环境变量。

    -m 改变用户身份的时候不改变环境变量

    -h 显示帮助信息

    要切换回原来的用户,使用命令“sudo su 用户名”即可

    • 显示文件内容命令 cat
    cat [选项] [文件]

    主要参数如下:

    -n 由 1 开始对所有输出的行进行编号。

    -b 和-n 类似,但是不对空白行编号。

    -s 当遇到连续两个行以上空白行的话就合并为一个行空白行。

    • 显示和配置网络属性命令 ifconfig

    ifconfig 是一个跟网络属性配置和显示密切相关的命令,通过此命令我们可以查看当前网络 属性,也可以通过此命令配置网络属性,比如设置网络 IP 地址等等

    ifconfig interface options | address

    主要参数如下:

    interface 网络接口名称,比如 eth0 等。

    up 开启网络设备。

    down 关闭网络设备。

    add IP 地址,设置网络 IP 地址。

    netmask add 子网掩码。

    • 系统帮助命令 man

    Ubuntu 提供了一个命令来帮助用户完成这个功能,那 就是“man”命令,通过“man”命令可以查看其它命令的语法格式、主要功能、主要参数说明等, “man”命令格式如下:

    man [命令名]

    例如,查询ls

    man ls

    输入指令后会跳出来一个资料文档

    • 系统重启命令 reboot

    直接输入命令“reboot”然后点击回车键即可

    • 系统关机命令 poweroff

    输入 命令“poweroff”然后按下回车键即可关闭 Ubuntu 系统

    2.4 Ubuntu软件安装

    • 通过APP Store安装

      使用apt工具安装软件,需要sudo,也就是root权限。

    • 使用APT工具安装

      使用apt包管理工具,apt可以自动下载,配置,安装。

      指令:sudo apt-get install + 软件

      安装git如下

    • deb软件包安装

      下载.deb软件包

      使用dpkg命令安装deb软件包,命令如下:

      sudo dpkg -i xxxx.deb

      在windows下,我们安装的是.exe文件,在Ubuntu就有一个.deb

      安装网易云音乐,

    • 自己下载程序源码编译安装

      Make

      Make install

    • 其他 安装方法

      QT扩展名是.run

    • 安装的软件启动图标位置

      以下路径中 usr/share/applications

    3.Ubuntu文件系统结构

    本小结学习目标:了解"/"根目录下各个文件包含内容的含义

    3.1 根目录

    Linux下“/”就是根目录!所有的目录都是由根目录衍生出来的

    3.2 其他文件目录(后期移植需要了解)

    目录功能
    /bin存放二进制可执行文件,这些命令在单用户模式下也能够使用,可以被root和一般的账号使用。
    /bootUbuntu内核和启动文件,比如vmlinuz-xxx。gurb引导装载程序。
    /dev设备驱动文件
    /etc存放一些系统配置文件,比如用户账号和密码文件,各种服务的起始地址。
    /home系统默认的用户主文件夹,一般创建用户账户的时候,默认的用户主文件夹都会放到此目录下。
    /lib存放库文件
    /media此目录下放置可插拔设备,比如SD卡,或者U盘就是挂载到这个目录中。
    /mnt用户可使用的挂载点,如果要挂载一些额外的设备,那么就可以挂载到此处。
    /opt可选的文件和程序存放目录,给第三方软件放置的目录。
    /rootroot用户目录,也就是系统管理员目录。
    /sbin和/bin类似,也是存放一些二进制可执行文件。sbin下面的一般是系统开机过程中所需要的命令。
    /srv服务相关目录。比如网络服务。
    /sys记录内核信息,虚拟文件系统。
    /tmp临时目录
    /var存放一些变化的文件,比如日志文件
    /usrusr不是user的缩写,而是UNIX Software Resource的缩写,存放于系统用户有关的文件,会占用很大的存储空间!
    /proc虚拟文件系统,数据放置到内存中,存放系统运行信息

    3.3 绝对路径与相对路径

    绝对路径:从根目录“/”算起的路径。

    相对路径:相对于目前路径的文件名写法,比如./home/zzk。不是以“/”开头的就行。

    “.” 代表当前路径,也可以 用“./”表示

    “…” 代表上一层目录,也可以用“…/”表示

    “*” 为通配符,表示全部

    4.Ubuntu磁盘管理

    本小节目标了解Ubuntu下磁盘的管理以及

    4.1 Ubuntu磁盘设备文件

    /dev/sd*文件,此类文件是磁盘设备文件(并不能直接访问磁盘,必须要将磁盘挂载到某一个目录下才可以访问)

    指令:定位到磁盘设备目录,显示所有sd开头设备

    cd \dev
    ls sd*

    /dev/sdb 和 /dev/sdb1 是U盘的设备文件。

    /dev/sdb表示U盘,/dev/sdb1表示U盘的第一个分区(当前U盘只有一个分区)

    4.2 磁盘和目录的容量查询命令

    ​ df:列出文件系统的整体磁盘使用量。主要查看个整个文件系统的使用量,

    ​ du:评估文件系统的磁盘使用量,主要查看单个文件的大小。

    两个指令都有各自的进一步衍生指令,指令太多,需要使用时查询即可

    4.3 磁盘挂载与卸载,分区和格式化

    1. 磁盘的挂载和卸载

      磁盘无法直接进入,需要进行挂载操作后才能进入,使用完毕再卸载

      mount(挂载)和umount(卸载)命令

    1. mount /dev/sdb1 + 挂载点 #挂载到指定挂载点
    2. umount /dev/sdb1	#卸载

    挂载到新建的usb文件夹,并进入查看文件

    卸载(卸载前先退出usb,不然无法退出)

    1. 磁盘分区

      fdisk命令

    sudo fdisk /dev/sdb
    #输入对应指令
    #执行

    创建一个分区

    sudo fdisk /dev/sdb
    n
    p
    2048 #开始扇区
    2097152 #(1024*1024*1024+2048)扇区结束长度

    sudo fdisk -l /dev/sdb #查询扇区信息

    已经创建1G分区

    1. 磁盘格式化

    ​ 磁盘分区创建好以后就可以格式化磁盘,使用命令mkfs。如:格式化sdb1分区

    mkfs -t vfat /dev/sd1

    5.Ubuntu压缩与解压缩

    5.1 Linux下常用的压缩格式

    Linux下常用的压缩扩展名有:.tar、.tar.bz2、.tar.gz与windows下的常用压缩包.rar、.zip有较大区别

    5.2 Window和Linux压缩工具

    5.2.1 Windows下7ZIP软件的安装

    因为Linux下很多文件是.bz2,.gz结尾的压缩文件,因此需要在windows下安装7ZIP软件(强大的压缩软件):链接

    5.2.2 Linux下压缩工具

    输入输入:工具名称–help 可查询 对应工具有关指令

    • gzip压缩工具

    .gzip工具负责压缩和解压缩.gz格式的压缩包。

    gzip xxx          #压缩
    gzip -d xxx.gz    #解压缩

    单个文件压缩与解压缩

    gzip对文件夹进行压缩

    gzip -r xxx       #对文件夹进行压缩
    gzip -rd xxx.gz   #对文件夹进行解压缩

    对test文件夹压缩与解压缩

    gzip虽然可以对文件夹进行压缩,但是并不能提供打包的服务,只是对文件夹中的所有文件进行了单独的压缩,例如上图中test内文件单独被压缩为.gz文件

    • bzip2压缩工具

    输入输入bzip2–help可查询bzip2有关指令

    和gzip类似,只是bzip2工具负责压缩和解压缩.bz2格式的压缩包。

    bzip2 -z xxx         #压缩
    bzip2 -d xxx.gz      #解压缩

    bzip只能对单个文件进行压缩和解压操作

    • tar打包工具
    tar常用工具参数:参数功能
    -f使用归档文件或 ARCHIVE 设备
    -c创建新归档,创建压缩文件
    -x从图档中解出文件,解压缩
    -j使用bzip2压缩格式。
    -z使用gzip压缩格式
    -v显示打包过程、结果

    tar工具提供打包服务,就是将多个文件打包(参数顺序有要求,注意顺序),比如

    tar -vcf test.tar test    #将test打包成test.tar
    tar -vxf test.tar       #解包

    打包test文件:

    解压test.tar文件:

    • tar压缩与解压缩(很常用)

    上面的tar命令只提供了打包和解包的功能,tar在提供打包和解包的同时使用gzip/bzip2进行压缩,实现类似windwos下winRAR软件的命令。

    1. 对.tar.bz2进行压缩和解压缩
    tar -vxjf xxx.tar.bz2    #解压缩
    tar -vcjf xxx.tar.bz2 xxx  #压缩
    1. 对.tar.gz进行压缩和解压缩
    tar -vxzf xxx.tar.gz    #解压缩
    tar -vczf xxx.tar.gz xxx  #压缩

    以gzip格式压缩test文件

    解压缩同理(注意解压后位置,默认为当前文件夹,不要出现重名文件夹)

    5.3 其他格式的压缩和解压缩

    5.3.1 .rar格式

    输入rar可查询rar有关指令

    需要先安装rar:sudo apt-get install rar

    rar x xxx.rar      #解压缩
    rar a xxx.rar xxx  #压缩

    解压缩测试

    5.3.2 .zip格式

    输入zip可查询zip有关指令

    zip格式压缩使用“zip“命令:

    zip -rv xxx.zip xxx

    zip格式解压缩使用“unzip”命令:

    unzip -v xxx.zip

    压缩与解压缩

    6.Ubuntu用户与用户组

    Linux是多用户系统,一个系统不仅仅只针对一个用户,而是多个用户,所以掌握用户与用户组的管理与操作很有必要;

    6.1 Linux用户

    Linux是一个多用户操作系统,不同的用户拥有不同的权限,可以查看和操作不同的文件,Ubuntu有三种用户:

    ● 初次创建的用户,此可以完成比普通更多功能。 初次创建的用户,此可以完成比普通更多功能。
    ● root用户,系统管理员中的BOSS拥有至高无上权利。
    ● 普通用户,安装完操作系统以后被创建的。 普通用户,安装完操作系统以后被创建的。

    Linux用户记录在/etc/passwd这个文件内,操作系统通过UID来识别是哪个用户,使用如下指令打开,用户显示方式:名称+UID+用户组GID

    sudo vi /etc/passwd #VI打开,退出方式为按下esc后按下shift + q

    Linux用户密码记录在/etc/shadow这个文件内,加密过

    sudo vi /etc/shadow #VI打开,退出方式为按下esc后按下shift + q

    每个用户都有一个ID,叫做UID。

    6.2 Linux用户组

    为了方便管理,将用户进行分组。这样就可以设置非本组人员不能访问某些文件。每个用户可以属于多个不同的组。

    • 用户与用户组区别:

    用户:家里有你、弟弟、妹妹个人,每个人都有自己的房间,你们三个人都是用户,你们都不能随便的乱翻别人的房间。

    用户组:你们三个都是一个家庭的,也就是属于同一个用户组,你们三个可以共用厨房,书房等空间。

    • 用户和用户组作用

    用户和用户组的存在就是为了控制文件的访问权限的。

    注意:每个用户组都有一个ID,叫做GID,用户组信息存储在/etc/group文件中

    6.3 创建用户和用户组

    • 图形化界面创建

    ​ 要使用图形化界面创建用户和用户组的话就需要安装gnome-system-tools这个工具:

    sudo apt-get install gnome-system-tools

    若出现以下BUG:

    E: 无法获得锁 /var/lib/apt/lists/lock - open (11: 资源暂时不可用)
    E: 无法对目录 /var/lib/apt/lists/ 加锁
    E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)
    E: 无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它?

    解决方法:

    sudo rm /var/cache/apt/archives/lock
    sudo rm /var/lib/dpkg/lock

    然后关掉终端重新打开,再次运行安装指令,安装成功后直接打开安装程序-用户和用户组就能创建和删除用户组了:

    • 命令创建用户和用户组

    添加用户:adduser命令**(备注:下面的添加和删除都需要root权限)**

    sudo adduser 用户名

    用户查询:finger命令

    finger 用户名

    修改用户密码:passwd命令,passwd 用户名

    删除用户:deluser命令

    sudo deluser 用户名

    添加用户组:addgroup命令

    sudo addgroup 用户组名

    显示组内用户名:groups命令,groups 用户组名

    删除用户组:delgroup命令

    sudo delgroup 用户组名

    7. 文件权限管理

    7.1 Ubuntu/Linux文件权限

    文件权限是指不同的用户或用户组对某个文件拥有的权限,文件的权限分为三种:

    命令字含义
    r
    w
    x可执行

    文件权限的描述形式如下:

    -rw-r–r--就是文件权限,第一位表示文件类型(例如c开头为字符设备,d开头为块设备),剩下的每三位表示一组权限。分别对应拥有者权限、拥有者所在组权限其他用户权限

    可以使用二进制表示文件权限

    权限二进制数字八进制数字
    0000
    –x0011
    -w-0102
    -wx0113
    r–1004
    r-x1015
    rw-1106
    rwx1117

    1.c的权限就是r=6,w=4,x=4

    1.c文件信息:- rw- r-- r–,表示:1.c所属用户拥有读写权限无可执行权限,组内其他用户拥有只读权限,其他用户仅有可读权限。

    7.2 Ubuntu/Linux文件权限修改

    1. 修改文件权限命令

    ​ chmod命令

    chmod [权限值] [文件名 /目录名] [参数]

    常用参数

    参数功能
    -c效果类似“ 效果类似“ -v”参数,但仅回显更改的部分
    -f不显示错误信息
    -r递归处理,即指定目录下所有文件以及子文件一起处理
    -v显示指令执行过程

    改变hollow的可执行权限

    1. 修改文件所属用户

    ​ chown命令

    chown [选项]... [所有者][:[组]] 文件...

    eg:

    chown root /u		将 /u的所属用户更改为"root"。

    8.Ubuntu连接文件(Linux通用)

    8.1 连接文件概念

    Linux有两种连接文件:符号连接(软连接)和硬链接

    • 符号链接(软连接):类似Windows下的快捷方式。

    • 硬链接:通过文件系统的inode连接来产生新文件名,而不是产生新文件。

    inode:记录文件属性,一个文件一个inode,inode相当于文件ID,查找文件的时候要先找到inode,然后才能读出文件的内容。

    8.2 ln命令

    ln命令用于创建连接文件:

    ln [选项] 源文件 目标文件

    选项:

    ​ -s 创建符号链接(软连接)

    ​ -f 强制创建连接文件,如果目标存在,那么先删除掉目标文件,然后再建立连接文件。

    8.3 硬连接

    硬链接是多个文件都指向同一个inode,硬链接知识点:

    ​ ① 具有相同inode的多个文件互为硬链接文件,创建硬链接相当于文件实体多了入口。

    ​ ② 对于硬链接文件,只有删除了源文件以及对应的所有硬连接文件,文件实体才会被删除。

    ​ ③ 根据硬链接文件的特点,我们可以通过给文件创建硬连接的方式来防止文件误删除。

    ​ ④ 不论修改源文件还是连接文件,另一个文件的数据都会被改变。

    ​ ⑤ 硬连接不能跨文件系统

    ​ ⑥ 硬连接不能连接到目录。

    因为以上这些限制,硬链接其实不常用。

    显示硬链接详细信息就是显示具体文件的信息

    8.4 符号连接(软连接)

    符号连接类似Windows下的快捷方式,符号链接也叫做软连接,软连接要用的多。符号连接相当于创建了一个独立的文件,这个文件会让数据读取指向它连接的哪个文件的文件名。软连接的特点:

    ​ ① 可以连接到目录。

    ​ ② 可以跨文件系统

    ​ ③ 删除源文件以后,软连接文件也就“打不开了”。

    ​ ④ 符号连接文件通过->来指示具体的连接文件。

    ​ ⑤ 符号连接要使用绝对路径,否则连接出问题。

    显示软连接详细信息就是显示软链接文件的详细信息,下图中显示的文件信息就是l(链接文件),所有用户都有操作权限!

    9.Vim编辑器常用操作

    9.1 vim编辑器

    Linux系统命令行的操作方式与图形化的操作方式不一样,他内部自带了vi编辑器,但是vi编辑器太难用,所以安装vim编辑器,安装命令:

    sudo apt-get install vim

    9.2 vim编辑器三种工作模式

    ​ vim xxx 使用vim编辑器打开文件。

    1. 一般模式(指令模式):默认模式,用vim打开一个软件以后自动进入到此模式。

    2. 编辑模式:一般模式中无法编辑文件,要编辑文件就要进入编辑模式,按下“i、I、a、A、o、O、s、r”等就会进入到编辑模式。一般按下“a”进入编辑模式。按下ESC键可退出编辑模式。

    3. 命令行模式(底行模式):先进入到一般模式,然后输入’:’、’/’、’?'这三个中的任意一个就可以进入到命令行模式。

    • 一般模式:

    常用指令:

    命令作用
    x删除光标所在处字符 nx 删除光标所在处后n个字符
    dd删除光标所在行,ndd删除n行
    dG删除光标所在行到末尾的内容
    D删除从光标所在处到行尾
    yy、Y复制当前行
    nyy、nY复制当前行以下n行
    dd剪切当前行
    ndd剪切当前行以下n行
    yy、Y复制当前行
    nyy、nY复制当前行以下n行
    dd剪切当前行
    ndd剪切当前行以下n行
    p、P粘贴在当前光标所在行下 或行上
    r取代光标所在处字符
    R(shift + r)从光标所在处开始替换字符,按Esc结束
    uundo,取消上一步操作
    ctrl+rredo,返回到undo之前
    • 编辑模式:

    常用指令:

    命令作用
    a在光标后附加文本
    A(shift + a)在本行行末附加文本 行尾
    i在光标前插入文本
    I(shift+i)在本行开始插入文本 行首
    o在光标下插入新行
    O(shift+o)在光标上插入新行
    • 底行模式:

    常用指令:

    命令作用
    :w保存修改
    :w new_filename另存为指定文件
    :w >> a.txt内容追加到a.txt文件中 文件需存在
    :wq保存修改并退出
    shift+zz(ZZ)快捷键,保存修改并退出
    :q!不保存修改退出
    :wq!保存修改并退出(文件所有者可忽略文件的只读属性)

    10.Linux下C编程入门

    10.1 编写C程序

    Linux下的编写C代码包括两部分:代码编写和编译,在 Windows 下可以使用 Visual Studio 直接完成这两部分,但在 Linux 下这两部分是分开的,我们先进行代码编写,编写完成以后再使用 GCC 编译器进行编译,其中代码编写工具很多,比如 VIM 编辑器、Emacs 编辑器、VScode 编辑器等等,此处我使用VIM编辑器来编写程序,把 Linux 下 的 C 编程完整的走一遍。

    10.1、设置vim编辑器

    用vim打开文件 /etc/vim/vimrc

    sudo vim /etc/vim/vimrc

    设置vim编辑器,一个TAB=4个字节,即在最后面输入如下指令

    set ts=4

    设置vim编译器,显示行号,最后面加入下面一行代码

    set nu

    10.2、编写C程序

    新建一个1.c文件(不新建C文件也可以,vim会自动创建)

    touch 1.c

    vim打开C文件

    vim 1.c

    根据上一小节vim操作输入如下c程序

    1 #include <stdio.h>
    2
    3 int main(void)
    4 {
    5     printf("Hello World\r\n");
    6     return 0;
    7 }

    保存退出

    10.2 编译C程序

    使用gcc编译器编译C程序。

    gcc -o hello 1.c

    执行程序

    补充GCC编译器介绍

    gcc [选项] [文件名字] [源文件]

    主要选项如下:

    -c:只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。

    -o:<输出文件名>用来指定编译结束以后的输出文件名,如果不使用这个选项的话 GCC 默 认编译出来的可执行文件名字为 a.out。

    -g:添加调试信息,如果要使用调试工具(如 GDB)的话就必须加入此选项,此选项指示编 译的时候生成调试所需的符号信息。

    -O:对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进 行优化,这样产生的可执行文件执行效率就高。

    -O2:比-O 更幅度更大的优化,生成的可执行效率更高,但是整个编译过程会很慢。

    注意gcc编译时,若C语言语法不对会报错显示!

    11.make工具和Makefile文件

    11.1 makehe1makefile介绍

    源码文件比较多的时候就不适合通过直接输入gcc命令来编译,这时候就需要一个自动化的编译工具.

    make :一般说GNU Make,是一个软件,用于将源代码文件编译为可执行的二进制文件,make工具主要用于完成自动化编译。make工具编译的时候需要Makefile文件提供编译文件

    Makefile :make工具所使用的文件,Makefile指明了编译规则

    11.2 编写C程序测试例程

    使用VIM编写多个小型的含有多个.c文件的C程序。

    编写主函数main.c文件

    1 #include <stdio.h>
    2 #include "input.h"
    3 #include "calcu.h"
    4
    5 int main(int argc, char *argv[])
    6 {
    7 int a, b, num;
    8
    9 input_int(&a, &b);
    10 num = calcu(a, b);
    11 printf("%d + %d = %d\r\n", a, b, num);
    12 }

    输入函数input.c

    1 #include <stdio.h>
    2 #include "input.h"
    3
    4 void input_int(int *a, int *b)
    5 {
    6 printf("input two num:");
    7 scanf("%d %d", a, b);
    8 printf("\r\n");
    9 }

    input的头文件input.h

    1 #ifndef _INPUT_H
    2 #define _INPUT_H
    3
    4 void input_int(int *a, int *b);
    5 #endif

    计算函数calcu.c

    1 #include "calcu.h"
    2
    3 int calcu(int a, int b)
    4 {
    5 return (a + b);
    6 }

    calcu的头文件calcu.h

    1 #ifndef _CALCU_H
    2 #define _CALCU_H
    3
    4 int calcu(int a, int b);
    5 #endif

    编写文件夹如下:

    11.3 使用GCC直接编译

    使用GCC直接编译的过程如下

    第一次编译使用

    gcc [所有文件] -o [目标文件]

    之后哪个文件更新了单独编译那个文件后再链接

    gcc [更新文件] -c
    gcc [所有文件.o] -o [目标文件]

    使用如下,先生成所有文件的.o文件,更新直接更新对应.o文件就行,最后再通过gcc的-o来链接所有编译后文件。

    gcc的编译方法复杂,尤其在文件数量很多时十分低效,所以引入Makefile来自动化编译,简化流程!

    11.3 使用make工具和Makefile文件进行编译

    以上面的文件为例子,进行makefile编译!

    第一次使用VIM编辑的话,首先修改文件/etc/vim/vimrc,使 TAB 键不用空格形成

    set noexpandtab

    Vim新建一个Makefile文件(严格按照大小写来)

    编写代码如下:(2、4、6、8、11、12处tab进位,必须!)

    1 main: main.o input.o calcu.o
    2     gcc -o main main.o input.o calcu.o
    3 main.o: main.c
    4     gcc -c main.c
    5 input.o: input.c
    6     gcc -c input.c
    7 calcu.o: calcu.c
    8     gcc -c calcu.c
    9
    10 clean:
    11     rm *.o
    12     rm main

    保存后,我们在命令行输入make就会默认执行main的程序

    使用make clean则会调用清除程序

    此处makefile的功能如下

    1. 如果工程没有编译过,那么工程中的所有.c 文件都要被编译并且链接成可执行程序。

    2. 如果工程中只有个别 C 文件被修改了,那么只编译这些被修改的 C 文件即可。

    3. 如果工程的头文件被修改了,那么我们需要编译所有引用这个头文件的 C 文件,并且 链接成可执行文件。

    11.4 Makefile语法入门

    • 规则格式

    Makefile由一系列的规则组成的,规则格式如下

    [目标]: [依赖]
    命令1
    命令2
    命令3
    ...

    比如上一小结的规则

    main : main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o

    这条规则的目标是 main,main.o、input.o 和 calcu.o 是生成 main 的依赖文件,如果要更新 目标 main,就必须先更新它的所有依赖文件,如果依赖文件中的任何一个有更新,那么目标也 必须更新,(更新就是执行一遍规则中的命令列表)

    命令列表中的每条命令必须以 TAB键开始,不能使用空格;make 命令会为 Makefile 中的每个以 TAB开始的命令创建一个 Shell进程去执行

    规则间的依赖关系如下:以上一节代码为例子

    main: main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o
    main.o: main.c
    gcc -c main.c
    input.o: input.c
    gcc -c input.c
    calcu.o: calcu.c
    gcc -c calcu.c
    
    clean:
    rm *.o
    rm main

    代码中有5条规则,最上面为默认规则,执行时会检查他的依赖文件是不是最新的,如果不是最新的就会向下搜索规则来生成最新的依赖文件,如果我们要直接执行对应规则,命令行输入如下指令就行,第五条规则因为没用依赖文件,默认认为依赖文件是最新的直接执行命令;

    make [规则目标]

    具体执行流程总结如下:

    1. make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
    2. 当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件。
    3. 当发现目标文件不存在,或者目标所依赖的文件比目标文件新**(也就是最后修改时间比目标文件晚)**的话就会执行后面的命令来更新目标。

    注意:除了第一条规则顺序有意义,其他规则顺序随意!

    • Makefile变量

    Makefile 加入了变量支持,不像 C 语言中的变量有 int、char 等各种类型,Makefile 中的变量都是字符串!类似 C 语言中的宏。使用变量将上面的代码修改,例如

    #Makefile 变量的使用
    objects = main.o input.o calcu.o
    main: $(objects)
    gcc -o main $(objects)

    先简单的补充一下上面用到的语法

    ’#‘ 为makfile语法中注释

    ’objects‘ 为变量名称

    ’$(变量名称)‘ 为引用变量

    ‘=’ 为对变量进行赋值

    • Makefile赋值符
    1. 赋值符“=”

      变量赋值,其真实值取决于它所引用的变量的最后一次有效值

      name = jk
      curname = $(name)
      name = jeck666
      
      print:
      @echo curname: $(curname)

      执行后结果,显示最后一次赋值

    2. 赋值符“:=”

      ‘:=’ 与 ‘=’ 号的区别在于,前者不会使用后面定义的变量,只能使用前面已经定义好的,这就是“=”和“:=”两个的区别,我们将代码换成如下代码进行测试

      name = jk
      curname := $(name)
      name = jeck666
      
      print:
      @echo curname: $(curname)

      可以看到值取的是赋值时的值,不是最后定义的变量值

    3. 赋值符“?=”
      “?=”使用时如果变量前面没有被赋值,那么此变量就是“?=”后面的值, 如果前面已经赋过值了,那么就使用前面赋的值

    4. 变量追加“+=”
      有时候我们需要给前面已经定义好的变量添加一些字符串进 去,此时就要使用到符号“+=”,比如如下所示代码

      objects = jeck
      objects += 666

      一开始变量objects为jeck,追加后变为jeck666

    • Makefile 模式规则

    模式规则中,至少在规则的目标定定义中要包涵“%”,否则就是一般规则,目标中的“%”表示对文件名的配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的 文件,类似与通配符,a.%.c 就表示以 a.开头,以.c结束的所有文件

    通过模式规则我们就可以使用一条规则来将所有的.c 文件编译为对应的.o 文件

    使用方法如下:

    %.o : %.c
    命令

    上一节代码可修改如下:

    main: main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o
    %.o: %.c
    命令
    
    clean:
    rm *.o
    rm main

    此处修了了之后命令也需要修改,因此引入自动化变量

    • Makefile自动化变量
    自动化变量变量
    $@规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模 式中定义的目标集合。
    $%当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件, 那么其值为空。
    $<依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么 “$<”就是符合模式的一系列的文件集合。
    $?所有比目标新的依赖目标集合,以空格分开。
    $^所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件, “$^”会去除重复的依赖文件,值保留一份。
    $+和“$^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。
    $*这个变量表示目标模式中"%"及其之前的部分,如果目标是 test/a.test.c,目标模 式为 a.%.c,那么“$*”就是 test/a.test。

    通过自动化变量,我们最终改版的代码如下:

    main: main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o
    %.o: %.c
    gcc -c $<
    
    clean:
    rm *.o
    rm main
    • Makefile 伪目标

    Makefile 有一种特殊的目标——伪目标,一般的目标名都是要生成的文件,而伪目标不代 表真正的目标名,使用伪目标主要是为了避免 Makefile 中定义的执行命令的目标和工作目录下的实际文件出 现名字冲突,例如上面的代码中clean规则,如果文件夹内真的存在clean命名的文件,那么clean规则就无法执行!!!因此,可以将 clean 声明为伪 目标,声明方式如下:

    .PHONY : clean

    上面实例代码进一步修改

    main: main.o input.o calcu.o
    gcc -o main main.o input.o calcu.o
    %.o: %.c
    gcc -c $<
    
    .PHONY : clean
    clean:
    rm *.o
    rm main

    声明 clean 为伪目标以后不管当前目录下是否存在名 为“clean”的文件,输入“make clean”的话规则后面的 rm 命令都会执行

    • Makefile条件判断

    makefile支持条件判断语法,具体有两种语法:

    <条件关键字>
    <条件为真时执行的语句>
    endif
    <条件关键字>
    <条件为真时执行的语句>
    else
    <条件为假时执行的语句>
    endif

    条件关键字有 4 个:ifeq、ifneq、ifdef 和 ifndef,这四个关键字其实分为两对、ifeq 与 ifneq、ifdef 与 ifndef,ifeq 用来判断是否相等,ifneq 判断是否不 相等,用法如下:

    ifeq (<参数 1>, <参数 2>)
    ifeq ‘<参数 1 >’,‘ <参数 2>’
    ifeq “<参数 1>”, “<参数 2>”
    ifeq “<参数 1>”, ‘<参数 2>’
    ifeq ‘<参数 1>’, “<参数 2>”

    ifdef 和 ifndef 的用法如下:

    ifdef <变量名>

    如果“变量名”的值非空,那么表示表达式为真,否则表达式为假。“变量名”同样可以是 一个函数的返回值。ifndef 用法类似,但是含义用户 ifdef 相反。

    • Makefile函数

    Makefile 中的函数是已经定义好的,我们直接使用, 不支持我们自定义函数。make 所支持的函数不多,但是绝对够我们使用了,函数的用法如下:

    $(函数名 参数集合)

    或者

    ${函数名 参数集合}

    常用函数:

    1. 函数 subst

    函数 subst 用来完成字符串替换,调用形式如下:

    $(subst <from>,<to>,<text>)

    将字符串中的内容替换为,函数返回被替换以后的字符串

    1. 函数 patsubst

    函数 patsubst 用来完成模式字符串替换,调用形式如下:

    $(patsubst <pattern>,<replacement>,<text>)

    此函数查找字符串中的单词是否符合模式,如果匹配就用来 替换掉,可以使用通配符“%”,表示任意长度的字符串,函数返回值就是替换后的字符串。如果中也包涵“%”,那么中的“%”将是中的那个 “%”所代表的字符串

    例如:

    $(patsubst %.c,%.o,a.c b.c c.c)
    1. 函数 dir

    函数 dir 用来获取目录,使用方法如下:

    $(dir <names…>)

    此函数用来从文件名序列中提取出目录部分,返回值是文件名序列的目录部分,/src/a.c的目录部分为/src

    1. 函数 notdir

    此函数用与从文件名序列中提取出文件名非目录部分,也就是提取文件名

    $(notdir <names…>)
    1. 函数 foreach

    foreach 函数用来完成循环

    $(foreach <var>,<list>,<text>)

    此函数的意思就是把参数中的单词逐一取出来放到参数中,然后再执行所 包含的表达式。每次都会返回一个字符串,循环的过程中,中所包含的每个字符串会以空格隔开,最后当整个循环结束时,所返回的每个字符串所组成的整个字符串将会是 函数 foreach 函数的返回值。

    1. 函数 wildcard

    通配符“%”只能用在规则中,只有在规则中它才会展开,如果在变量定义和函数使用时, 通配符不会自动展开,这个时候就要用到函数 wildcard

    $(wildcard PATTERN…)

    例如:

    $(wildcard *.c)

    获取当前目录下所有的.c 文件

    12.Shell脚本入门基础

    12.1 什么是shell脚本

    之前我们已经了解到终端下输入的一些常用Shell命令,但是我们都是一条一条输入命令,遇到大量的指令时会很

    麻烦,所以我们通过shell脚本一次性执行大量指令!shell脚本类似windows的批处理文件,就是将连续执行的命

    令写成一个文件,shell脚本提供数组、循环、条件判断的等功能,shell脚本一般是Linux运维或者系统管理员

    要掌握的,作为嵌入式开发人员,我们只需要掌握shell脚本最基础的部分即可。

    12.2 shell脚本写法

    shell脚本是个纯文本文件,命令从上而下,一行一行的开始执行,shell脚本扩展名为.sh,shell脚本第一行一定要为:

    #!/bin/bash

    表示使用bash,因为linux里面不仅仅只有bash一个解析器,还有其它的,它们之间的语法会有一些不同,所以加上这一句话,告诉系统要用这个解析器

    12.3 shell基本语法

    • shell变量

    定义变量时,变量名不加美元符号

    name=“666”

    name为定义的变量

    使用定义过的变量,只要在变量名前面加美元符号$,格式如下

    echo $name
    echo ${name}
    • shell输出

    echo 指令用于字符串的输出,使用格式如下

    #显示字符串
    echo "It is a test"
    #显示变量
    echo "$name It is a test"
    # #号为shell中注释符号
    • shell读取

    read指令用于读取,可以带有-a, -d, -e, -n, -p, -r, -t, -s八个选项,语法如下

    read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]

    8个参数功能描述

    参数功能
    -d后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志。
    -p后面跟提示信息,即在输入前打印提示信a息
    -e在输入的时候可以使用命令补全功能。
    -n后跟一个数字,定义输入文本的长度,很实用。
    -r屏蔽\,如果没有该选项,则\作为一个转义字符,有的话 \就是个正常的字符了。
    -s安静模式,在输入字符时不再屏幕上显示,例如login时输入密码。
    -t后面跟秒数,定义输入字符的等待时间。
    -u后面跟fd,从文件描述符中读入,该文件描述符可以是exec新开启的
    • shell数值计算

    shell脚本中数值仅支持整形,数值计算表达式如下

    $((表达式))

    例如:

    #!/bin/basha=1
    b=2
    c=$((a+b))
    echo "$a+$b=$c"
    

    注意:shell语法内 ‘=’号的使用前后不能有间隔!

    • shell的test命令

    test命令用于查看文件是否存在、权限等信息,可以进行数值,字符,文件三方面的测试。

    数值测试

    参数说明
    -eq等于则为真
    -ne不等于则为真
    -gt大于则为真
    -ge大于等于则为真
    -lt小于则为真
    -le小于等于则为真

    字符串测试

    参数说明
    =等于则为真
    !=不相等则为真
    -z 字符串字符串的长度为零则为真
    -n 字符串字符串的长度不为零则为真

    文件测试

    参数说明
    -e 文件名如果文件存在则为真
    -r 文件名如果文件存在且可读则为真
    -w 文件名如果文件存在且可写则为真
    -x 文件名如果文件存在且可执行则为真
    -s 文件名如果文件存在且至少有一个字符则为真
    -d 文件名如果文件存在且为目录则为真
    -f 文件名如果文件存在且为普通文件则为真
    -c 文件名如果文件存在且为字符型特殊文件则为真
    -b 文件名如果文件存在且为块特殊文件则为真

    &&和||命令:

    **cmd1 && cmd2:**当cmd1执行完并且正确,那么cmd2开始执行,如果cmd1执行完毕错误,那么cmd2不执行。

    cmd1 || cmd2: 当cmd1执行完毕并正确,那么cmd2不执行,反之cmd2执行。

    根据以上指令编写测试程序

    #!/bin/bashecho "please input two string:"
    read -p "first:" str1 #一一对应输入参数
    read -p "second:" str2
    #运用 && 和 || 判断test结果
    test $str1 == $str2 && echo "str1 = str2" || echo "str1 != str2"
    

    测试结果

    • shell中括号[]判断符

    [ ]为test命令的另一种形式,但要注意:

    1.必须在左括号的右侧和右括号的左侧各加一个空格,否则会报错。

    2.test命令使用标准的数学比较符号来表示字符串的比较,而用文本符号来表示数值的比较。

    3.大于符号或小于符号必须要转义,否则会被理解成重定向。

    [ ] 将判断内容框起来,代替test判断结果,使用方法如下

    [ "$str1"=="str2" ]

    注意:参数必须加""号表示一个整体参数,[]与内容必须间隔一个空格

    • shell默认变量

    shell脚本提供许多默认参数,具体如下:

    参数作用
    $0输出当前执行脚本的路径
    $n运行脚本时,后面跟的参数,例:./test.sh 1 2 3 那么在test.sh中,$0=./test.sh ,$1=1 ,$2=2,$3=4
    $#命令行参数的个数
    $@所有参数的值,每个参数用引号包起来
    $*所有参数的值,所有参数用一个引号包起来
    $?判断上一条命令是否执行成功
    $$获得当前进程进程号
    $!上一个指令的PID
    $_在执行此命令之前的前一个命令

    主要介绍如下一个:

    0   0~ 0 n,表示shell脚本的参数,包括shell脚本命令本身,shlle脚本执行脚本的路径为$0,$1-n则可以在我们运行脚本时直接传入参数,例如以下代码

      1 #!/bin/bash2 echo "input dat=" $1
    3 echo "pos of shell=" $0
    

    运行结果

    • shell条件判断

    shell脚本支持条件判断,虽然可以通过&&和||来实现简单的条件判断,但是稍微复杂一点的场景就不适合了。shell脚本提供了if then条件判断语句,写法

    if [条件判断] ; then
    #判断成立要做的事情
    fi

    还有if then else 语句,写法

    if [条件判断] ; then
    #条件判断成立要做的事情
    else
    #条件判断不成立要做的事情。
    fi

    或:

    if [条件判断] ; then
    #条件判断成立要做的事情
    elif [条件判断]; then
    #条件判断成立要做的事情
    else
    #条件判断不成立要做的事情。
    fi

    实例代码:

      1 #!/bin/bash2 echo "please input two string:"
    3 read -p "first:" str1 #一一对应输入参数
    4 read -p "second:" str2
    5
    6
    7
    8 if [ "&str1"=="$str2" ] ; then
    9     echo "str1=str2"
    10 else
    11     echo "str1!=str2"
    12 fi
    

    执行结果

    最后还有case语句

    case $变量 in
    “第1个变量内容”)
    程序段
    ;;   #表示该程序块结束!!
    
    “第2个变量内容”)
    程序段
    ;;
    
    “第n个变量内容”)
    程序段
    ;;
    esac

    示例代码:

      1 #!/bin/bash2 case $1 in
    3 "a")
    4    echo "dat A"
    5    ;;   #表示该程序块结束!!
    6
    7 "b")
    8    echo "dat B"
    9    ;;
    10
    11 *)     # *号表示其他所有情况
    12    echo "dat other"
    13    ;;
    14 esac
    

    执行结果:

    • shell函数

    shell脚本支持自定义函数,函数写法如下:

    [ function ] funname [()]
    
    {
    #代码段;
    [return int;]
    }

    说明:

    1. 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。

    2. 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255

    实例代码

    #!/bin/bash
    function help()
    {
    case $1 in
    "-a")
    echo "help a"
    ;;
    
    "-b")
    echo "help b"
    ;;
    
    *)     # *号表示其他所有情况
    echo "unknow"
    ;;
    esac
    }
    
    #执行函数
    help -a
    
    help -b
    
    help -c
    
    

    运行结果

    • shell循环

    shell脚本也支持循环,比如 while do done,表示当条件成立的时候就一直循环,直到条件不成立,写法如下:

    while [条件]  #括号内的状态是判断式
    do         #循环开始
    #循环代码段
    done

    还有另外一种until do done,表示条件不成立的时候循环,条件成立以后就不循环,写法如下:

    until [条件]
    do
    #循环代码段
    done

    示例循环代码:

      1 #!/bin/bash2 read -p "please input name:" name
    3
    4 while [ "$name" == "jeck" ]
    5 do
    6     read -p "please input name:" name
    7 done
    8 echo "While Over!"
    

    运行结果:

    for循环,使用for循环可以知道循环次数,写法:

    for var in con1 con2 con3……
    do
    #循环代码段
    done

    示例代码:

    #!/bin/bashfor var in a b c d e
    do
    echo $var
    done
    

    执行结果,依次输出:

    for循环数值处理,写法:

    for((初始值; 限制值; 执行步长))
    do
    #循环代码段
    done

    示例代码:

    #!/bin/bashfor((i=0; i<5; i++))
    do
    echo $i
    done
    

    执行结果如下:

    以上就是做Linux驱动开发时需要的Ubuntu入门知识了,后期我还会更新Linux下IMX6ULL裸机开发的学习教程,欢迎大家点个关注和收藏哇!另外如果文章内容有错误的话,欢迎大家在评论区指正呀,如果你需要PDF版本的文章,也欢迎留下邮箱哦!

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: