2021 Archlinux双系统安装教程(超详细) - 知乎 (zhihu.com)
搭建samba共享服务:archlinux samba服务器搭建配置及访问_zyykkk的博客-CSDN博客
不能访问samba问题解决:win10访问不了samba共享文件夹解决方法-百度经验 (baidu.com)
安装openssh,arch linux 默认防火墙没有开
切换到root用户:su -l root
报“xxx is not in the sudoers file.This incident will be reported” 错误解决方法:Ubuntu报“xxx is not in the sudoers file.This incident will be reported” 错误解决方法_Linux教程_Linux公社-Linux系统门户网站 (linuxidc.com)
vim:
set ts=4#TAB空4格
set nu#显示行号
set noexpandtab#空格代替TAB键
NFS:
pacman -S nfs-utils
vim /etc/exports
/home/xingxingye/linux/nfs *(rw,sync,no_root_squash)
systemctl restart nfs-server.service
systemctl enable nfs-server.service
u-boot NFS下载文件报错:Loading: *** ERROR: File lookup fail解决方法:u-boot NFS下载文件报错:Loading: *** ERROR: File lookup fail解决方法_polaris_zgx的博客-CSDN博客
挂载:mount -t nfs 192.168.50.101:/home/xingxingye/linux/nfs /mnt -o nolock,nfsvers=3
nolock表示去掉文件锁,vers=3表示是用nfs 3.0进行挂载
FTP 服务:
FTP:vsftpd vim /etc/vsftpd.conf local_enable=YES write_enable=YES
windows 安装:FileZilla https://www.filezilla.con/download
TFTP 服务器:需要安装 tftp-hpa 和 tftpd-hpa
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd
配置 tftp,安装完成以后编辑文件/etc/xinetd.d/tftp,内容如下:
server tftp { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /home/xingxingye/linux/tftpboot disable = no per_source = 11 cps = 100 2 flags = IPv4 }
打开/etc/default/tftpd-hpa 文件,将其修改为如下所示内容:
# /etc/default/tftpd-hpa TFTP_USERNAME="tftp" TFTP_DIRECTORY="/home/zuozhongkai/linux/tftpboot" TFTP_ADDRESS=":69" TFTP_OPTIONS="-l -c -s"
uboot: http://www.denx.de/wiki/U-Boot/
快速查询linux帮助手册:pacman -S man-pages
驱动开发:
面试题:(3条消息) linux驱动最新面试题(面试题整理,含答案)_不忘初心-CSDN博客_linux驱动面试题
交叉编译器:Linaro https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/ (建议使用4.9版本)
安装相关库:sudo apt-get install lsb-core lib32stdc++6
arch: lsb-release lib32-glibc
ubuntu:20.04—64位版本 要下载安装 lib32z1库直接sudo apt-get install lib32z1
bootcmd:tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000
bootargs:
console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.1.250:/home/zuozhongkai/linux/nfs/ rootfs ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off
错误:multiple definition of `yylloc‘:新版本gcc(gcc10.x)编译Linux内核,错误:multiple definition of `yylloc‘_Imagine Miracle_wxn的博客-CSDN博客
设备树详解:(2条消息) 设备树详解_XiaoBaWu的博客-CSDN博客
Cortex-A7 MPCore 架构(参看书籍:《Cortex-A7 Technical ReferenceManua.pdf》和《ARM Cortex-A(armV7)编程手册 V4.0.pdf》 这两份文档都是 ARM 官方的文档,详细的介绍了 Cortex-A7 架构和ARMv7-A 指令集)
Cortex-A 寄存器组:《ARM Cortex-A(armV7)编程手册 V4.0.pdf》的“第 3 章 ARM Processor Modes And Registers”
《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf》:主要讲解 ARMv7-A 和 ARMv7-R 指令集的开发,Cortex-A7 使用的是 ARMv7-A 指令集
《ARM Cortex-A(armV7)编程手册 V4.0.pdf》:主要讲解 Cortex-A(armV7)编程的
DTS 语法规则:《 Devicetree SpecificationV0.2.pdf 》 和《Power_ePAPR_APPROVED_v1.12.pdf》
想系统的学习 Cortex-A的指令:《ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf》的 A4 章详细的讲解了 Cortex-A 的汇编指令
I.MX6U 的 IO 是怎么命名的:I.MX6ULL 参考手册的第 32 章“Chapter 32: IOMUX Controller(IOMUXC)”,第 32 章的书签
I.MX6U IO 复用:参考手册的 1568 页
GNU 汇编语法:ARM汇编,编译使用的 GCC 交叉编译器,所以我们的汇编代码要符合 GNU 语法
GNU 汇编语法适用于所有的架构,并不是 ARM 独享的,GNU 汇编由一系列的语句组成,每行一条语句,每条语句有三个可选部分,如下:
label:instruction @ comment
label 即标号,表示地址位置,有些指令前面可能会有标号,这样就可以通过这个标号得到指令的地址,标号也可以用来表示数据地址。注意 label 后面的“:”,任何以“:”结尾的标识符都会被识别为一个标号。
instruction 即指令,也就是汇编指令或伪指令。@符号,表示后面的是注释,就跟 C 语言里面的“/*”和“*/”一样,其实在 GNU 汇编文件中我们也可以使用“/*”和“*/”来注释。comment 就是注释内容。
比如如下代码:
add:
MOVS R0, #0X12 @设置 R0=0X12
上面代码中“add:”就是标号,“MOVS R0,#0X12”就是指令,最后的“@设置 R0=0X12”就是注释。
注意!ARM 中的指令、伪指令、伪操作、寄存器名等可以全部使用大写,也可以全部使用
小写,但是不能大小写混用。
//
用户可以使用.section 伪操作来定义一个段,汇编系统预定义了一些段名:
.text 表示代码段。
data 初始化的数据段。
.bss 未初始化的数据段。
.rodata 只读数据段。
我们当然可以自己使用.section 来定义一个段,每个段以段名开始,以下一段名或者文件结尾结束,比如:
.section .testsection @定义一个 testsetcion 段
汇编程序的默认入口标号是_start,不过我们也可以在链接脚本中使用 ENTRY 来指明其它的入口点,下面的代码就是使用_start 作为入口标号:
.global _start
_start:
ldr r0, =0x12 @r0=0x12
上面代码中.global 是伪操作,表示_start 是一个全局标号,类似 C 语言里面的全局变量一样,常见的伪操作有:
.byte 定义单字节数据,比如.byte 0x12。
.short 定义双字节数据,比如.short 0x1234。
.long 定义一个 4 字节数据,比如.long 0x12345678。
.equ 赋值语句,格式为:.equ 变量名,表达式,比如.equ num, 0x12,表示 num=0x12。
.align 数据字节对齐,比如:.align 4 表示 4 字节对齐。
.end 表示源文件结束。
.global 定义一个全局符号,格式为:.global symbol,比如:.global _start。
GNU 汇编还有其它的伪操作,但是最常见的就是上面这些,如果想详细的了解全部的伪操作,可以参考《ARM Cortex-A(armV7)编程手册 V4.0.pdf》的 57 页。
////////
I/O端口:当外部寄存器或内存映射到I/O空间
I/O内存:当外部寄存器或内存映射到内存空间
Linux 字符设备驱动结构(一)—— cdev 结构体、设备号相关知识解析:(1条消息) Linux 字符设备驱动结构(一)—— cdev 结构体、设备号相关知识解析_知秋一叶-CSDN博客
Linux内核 设备树操作常用API:Linux内核 设备树操作常用API_Linux教程_Linux公社-Linux系统门户网站 (linuxidc.com)
进度:4.3
应用开发:
基础知识:文件IO操作,文件高级IO,文件属性,系统信息,进程,线程,进程间通信,信号以及线程同步等内容。
硬件外设:LED,GPIO,PWM,串口,摄像头,LCD,看门狗,音频,网络编程(重点)
网络基础知识:网络编程架构,网卡,路由器,交换机,TCP/IP协议 socket接口进行网络编程开发。
书籍推荐:《UNIX 环境高级编程》、《Linux/UNIX 系统编程手册》(分为上册和下册)、《UNIX 网络编程》
C 语 言 库:GNU C语言(glibc) http://www.gnu.org/software/libc/
//////////////////////////////////////////////////eclipse/////////////////////////////////////////////
eclipse:
桌面不显示问题解决:在Desktop 目录下传创建eclipse.desktop,为 eclipse.desktop 文件添加上可执行权限:chmod u+x eclipse.desktop
arch:
https://www.cnblogs.com/huapox/archive/2012/03/01/3299974.html
style “eclipse” { font_name = “DejaVu 8″ } class “GtkWidget” style “eclipse” style “eclipse” { font_name = “DejaVu 8″ } class “GtkWidget” style “eclipse”
其中字体的名字和大小可以根据自己喜好进行设置。完成后在桌面上创建一个程序启动器,在其命令那里写入:
ubuntu:
[Desktop Entry] Encoding=UTF-8 Name=Eclipse Comment=Eclipse Exec=/opt/eclipse/eclipse Icon=/opt/eclipse/icon.xpm Terminal=false StartupNotify=true Type=Application Categories=Application;Development;
jdk:
jdk环境配置:
# jdk 环境配置
export JDK_HOME=/opt/jdk1.8.0_291
export JRE_HOME=${JDK_HOME}/jre
export CLASSPATH=.:${JDK_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export PATH=${JDK_HOME}/bin:$PATH
ubuntu:
~/.bashrc
arch:
/etc/profile
source 配置文件 java -version 检测版本
在esclise目录下创建jre文件夹
创建软链接:ln -s /opt/jdk1.8.0_291/bin
//////////////////////////////////////////////////eclipse/////////////////////////////////////////////
文件IO基础运用学习:open close read write sleek 头文件:#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h>
文件描述符复制:int dup(int oldfd);
int dup2(int oldfd, int newfd);//指定一个文件描述符(需要指定一个当前进程没有使用到的文件描述符)。
文件共享的核心是:如何制造出多个不同的文件描述符来指向同一个文件。
//
int fcntl(int fd, int cmd, ... /* arg */ );
fcntl()函数可以对一个已经打开的文件描述符执行一系列控制操作,譬如复制一个文件描述符(与 dup、 dup2 作用相同)、获取/设置文件描述符标志、获取/设置文件状态标志等,类似于一个多功能文件描述符管 理工具箱。
⚫ 复制文件描述符(cmd=F_DUPFD 或 cmd=F_DUPFD_CLOEXEC);
⚫ 获取/设置文件描述符标志(cmd=F_GETFD 或 cmd=F_SETFD);
⚫ 获取/设置文件状态标志(cmd=F_GETFL 或 cmd=F_SETFL);
⚫ 获取/设置异步 IO 所有权(cmd=F_GETOWN 或 cmd=F_SETOWN);
⚫ 获取/设置记录锁(cmd=F_GETLK 或 cmd=F_SETLK);
//
int ioctl(int fd, unsigned long request, ...);
ioctl()可以认为是一个文件 IO 操作的杂物箱,可以处理的事情非常杂、不统一,一般用于操作特殊文件 或硬件外设
//
截断文件:使用系统调用 truncate()或 ftruncate()可将普通文件截断为指定字节长度
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
这两个函数的区别在于:ftruncate()使用文件描述符 fd 来指定目标文件,而 truncate()则直接使用文件路 径 path 来指定目标文件,其功能一样。
调用这两个函数并不会导致文件读写位置偏移量发生改变
//
每个进程启动之后都会默认打开标准输入、标准输出以及标准错误,得到三个文件描述符,即 0、1、 2,其中 0 代表标准输入、1 代表标准输出、2 代表标准错误;在应用编程中可以使用宏 STDIN_FILENO、 STDOUT_FILENO 和 STDERR_FILENO 分别代表 0、1、2,这些宏定义在 unistd.h 头文件中:
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO1 /* Standard output. */
#define STDERR_FILENO2 /* Standard error output. */
0、1、2 这三个是文件描述符,只能用于文件 I/O(read()、write()等),那么在标准 I/O 中,自然是无 法使用文件描述符来对文件进行 I/O 操作的,它们需要围绕 FILE 类型指针来进行,在 stdio.h 头文件中有相 应的定义,如下:
/* Standard streams. */
extern struct _IO_FILE *stdin; /* Standard input stream. */
extern struct _IO_FILE *stdout; /* Standard output stream. */
extern struct _IO_FILE *stderr; /* Standard error output stream. */
/* C89/C99 say they're macros. Make them happy. */
#define stdin stdin
#define stdout stdout
#define stderr stderr
Tips:struct _IO_FILE 结构体就是 FILE 结构体,使用了 typedef 进行了重命名。 所以,在标准 I/O 中,可以使用 stdin、stdout、stderr 来表示标准输入、标准输出和标准错误。
//
long ftell(FILE *stream);
库函数 ftell()可用于获取文件当前的读写位置偏移量
//
int feof(FILE *stream);
库函数 feof()用于测试参数 stream 所指文件的 end-of-file 标志,如果 end-of-file 标志被设置了,则调用 feof()函数将返回一个非零值,如果 end-of-file 标志没有被设置,则返回 0。
//
int ferror(FILE *stream);
库函数 ferror()用于测试参数 stream 所指文件的错误标志,如果错误标志被设置了,则调用 ferror()函数 将返回一个非零值,如果错误标志没有被设置,则返回 0。
//
void clearerr(FILE *stream);
库函数 clearerr()用于清除 end-of-file 标志和错误标志,当调用 feof()或 ferror()校验这些标志后,通常需 要清除这些标志,避免下次校验时使用到的是上一次设置的值,此时可以手动调用 clearerr()函数清除标志。
//
格式化输出:printf()、fprintf()、dprintf()、sprintf()、snprintf()
格式化输入:scanf()、 fscanf()、sscanf()
///
I/O缓冲:
出于速度和效率的考虑,系统 I/O 调用(即文件 I/O,open、read、write 等)和标准 C 语言库 I/O 函数
(即标准 I/O 函数)在操作磁盘文件时会对数据进行缓冲;
文件拷贝完成之后,通常在拔掉 U 盘之前,执行 sync 命令进行同步操作,这个同步操作其实就是将文件 I/O 内核缓冲区中的数据更新到 U 盘硬件设备
Linux 中提供了一些系统调用可用于控制文件 I/O 内核缓冲,包括系统调用 sync()、syncfs()、fsync()以及 fdatasync()。
直接 I/O:绕过内核缓冲
从 Linux 内核 2.4 版本开始,Linux 允许应用程序在执行文件 I/O 操作时绕过内核缓冲区,从用户空间直接将数据传递到文件或磁盘设备,把这种操作也称为直接 I/O(direct I/O)或裸 I/O(raw I/O)
针对某一文件或块设备执行直接 I/O,要做到这一点,需要在调用 open()函数打开文件时,指定O_DIRECT 标志,该标志至 Linux 内核 2.4.10 版本开始生效
直接 I/O 的对齐限制
因为直接 I/O 涉及到对磁盘设备的直接访问,所以在执行直接 I/O 时,必须要遵守以下三个对齐限制要
求:
⚫ 应用程序中用于存放数据的缓冲区,其内存起始地址必须以块大小的整数倍进行对齐;
⚫ 写文件时,文件的位置偏移量必须是块大小的整数倍;
⚫ 写入到文件的数据大小必须是块大小的整数倍。
如果不满足以上任何一个要求,调用 write()均为以错误返回 Invalid argument。以上所说的块大小指的
是磁盘设备的物理块大小(block size),常见的块大小包括 512 字节、1024 字节、2048 以及 4096 字节
如何确定磁盘分区的块大小呢?可以使用 tune2fs 命令进行查看,如下所示:
tune2fs -l /dev/sda1 | grep "Block size"
-l 后面指定了需要查看的磁盘分区,可以使用 df -h 命令查看 Ubuntu 系统的根文件系统所挂载的磁盘分
区
__attribute((aligned (4096)))修饰,使其起始地址以 4096 字节进行对其
__attribute 是 gcc 支持的一种机制(也可以写成__attribute__),可用于设置函数属性、变量属性以及类型属性等
文件 I/O 内核缓冲区和 stdio 缓冲区之间的联系与区别
////////////////////////////////////////////////////////////////////
Linux 系统中的文件类型(7种):
1.普通文件:分为两大类:文本文件和二进制文件
2.目录文件:directory
3.字符设备文件和块设备文件
字符设备文件(character)、块设备文件(block)
4.符号链接文件:
cdrom、cdrw、fd、initctl 等这些文件都是符号链接文件,箭头所指向的文件路径便是符号链接文件所指向的文件
5.管道文件:管道文件(pipe)主要用于进程间通信
6.套接字文件:
套接字文件(socket)也是一种进程间通信的方式,与管道文件不同的是,它们可以在不同主机上的进
程间通信,实际上就是网络通信
//
普通文件是最常见的文件类型;
目录也是一种文件类型;
设备文件对应于硬件设备;
符号链接文件类似于 Windows 的快捷方式;
管道文件用于进程间通信;
套接字文件用于网络通信。
S_IFSOCK 0140000 socket(套接字文件)
S_IFLNK 0120000 symbolic link(链接文件)
S_IFREG 0100000 regular file(普通文件)
S_IFBLK 0060000 block device(块设备文件)
S_IFDIR 0040000 directory(目录)
S_IFCHR 0020000 character device(字符设备文件)
S_IFIFO 0010000 FIFO(管道文件)
S_IFMT 宏是文件类型字段位掩码:S_IFMT 0170000
除了这样判断之外,我们还可以使用 Linux 系统封装好的宏来进行判断,如下所示(m 是 st_mode 变
量):
S_ISREG(m)
#判断是不是普通文件,如果是返回 true,否则返回 false
S_ISDIR(m)
#判断是不是目录,如果是返回 true,否则返回 false
S_ISCHR(m)
#判断是不是字符设备文件,如果是返回 true,否则返回 false
S_ISBLK(m)
#判断是不是块设备文件,如果是返回 true,否则返回 false
S_ISFIFO(m)
#判断是不是管道文件,如果是返回 true,否则返回 false
S_ISLNK(m)
#判断是不是链接文件,如果是返回 true,否则返回 false
S_ISSOCK(m)
#判断是不是套接字文件,如果是返回 true,否则返回 false
//
当系统关机时,设备文件都会消失;字符设备文件一般存放在 Linux 系统/dev/目录下,所以/dev 也称为虚拟文件系统 devfs
对于硬链接来说,存在一些限制情况,如下:
⚫ 不能对目录创建硬链接(超级用户可以创建,但必须在底层文件系统支持的情况下)。
⚫ 硬链接通常要求链接文件和源文件位于同一文件系统中。
而软链接文件的使用并没有上述限制条件,优点如下所示:
⚫ 可以对目录创建软链接;
⚫ 可以跨越不同文件系统;
⚫ 可以对不存在的文件创建软链接。
strtoul、strtoull 函数
这两个函数使用方法与 strtol()、
strtoll()一样,区别在于返回值的类型不同,
strtoul()返回值类型是 unsigned long int,strtoull()返回值类型是 unsigned long long int
jiffies 是内核中定义的一个全局变量,内核使用 jiffies 来记录系统从启动以来的系统节拍数,所以这个
变量用来记录以系统节拍时间为单位的时间长度,Linux 内核在编译配置时定义了一个节拍时间,使用节拍
率(一秒钟多少个节拍数)来表示,譬如常用的节拍率为 100Hz
clock_t clock(void);//
库函数 clock()提供了一个更为简单的方式用于进程时间,它的返回值描述了进程使用的总的 CPU 时间
(也就是进程时间,包括用户 CPU 时间和系统 CPU 时间)
clock_t times(struct tms *buf);//
分配对其内存:posix_memalign()、aligned_alloc()、memalign()、valloc()、pvalloc()
int posix_memalign(void **memptr, size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void *valloc(size_t size);
#include <malloc.h>
void *memalign(size_t alignment, size_t size);
void *pvalloc(size_t size);
/proc 目录
⚫ cmdline:内核启动参数;
⚫ cpuinfo:CPU 相关信息;
⚫ iomem:IO 设备的内存使用情况;
⚫ interrupts:显示被占用的中断号和占用者相关的信息;
⚫ ioports:IO 端口的使用情况;
⚫ kcore:系统物理内存映像,不可读取;
⚫ loadavg:系统平均负载;
⚫ meminfo:物理内存和交换分区使用情况;
⚫ modules:加载的模块列表;
⚫ mounts:挂载的文件系统列表;
⚫ partitions:系统识别的分区表;
⚫ swaps:交换分区的利用情况;
⚫ version:内核版本信息;
⚫ uptime:系统运行时间;
进度:8.4.2