一、Linux环境搭建
1.gdb调试
1.gdb -q Filename 进入gdb调试器
2.(gdb)b 3 在第三行添加断点 breakpoint
3.(gdb) run 执行程序
4.(gdb)whatis iNum 查看iNum的数据类型
5.(gdb) c 继续执行程序(直到下一个断点或者之后没有断点就运行完整个程序)
6.(gdb) n 一步一步执行程序
7.(gdb) p iNum 输出iNum值 (gdb中变量的值是每一步执行之前的数字)
2.Makefile
从源码到可执行文件的四个阶段:
- 预处理(.c -> .i)
- gcc -E test.c -o test.i
- 编译 (.i -> .s) 得到汇编语言代码
- gcc -S test.i -o test.s
- 汇编 (.s -> .o) 得到机器语言代码
- gcc -c test.s -o test.o
- 链接 (.o -> ) 得到可执行文件
- gcc test.o -o test
gcc(选项)(参数):
-o:指定生成的输出文件;
-On:n为数字1~3,使用编译优化级别n编译程序;
-E:仅执行编译预处理;
-S:将C代码转换为汇编代码;
-Wall:显示警告信息;
-c:仅执行编译操作,不进行链接操作。
3.tmux使用
Ctrl + b, shift + % 新建左右窗格
Ctrl + b, shift + “ 新建上下窗格
Ctrl + b, x 删除当前窗格
4.编译nemu的坑
make menuconfig命令后出现如下情况:
1 | /home/lixuanbo/Desktop/ysyx/ysyx-workbench/nemu/scripts/config.mk:20: Warning: .config does not exists! |
1 | CC confdata.c |
解决方法:要安装词法分析和语法分析工具 flex和bison
二、搭建verilator仿真环境
1.【一生一芯】搭建verilator仿真环境 - 老吴家的小阿哲 - 博客园 (cnblogs.com)
2.verilator探幽
(1)一个简单的例子
1.将verilog代码写入文件top.v
2.将**C++**代码写入文件sim_main.cpp
3.使用下面的命令来运行Verilator:
1 | verilator --cc --exe --build -j 0 -Wall sim_main.cpp top.v |
4.使用 ./obj_dir/Vtop 来运行Verilator生成的可执行程序
(2)稍微复杂的例子
在Verilog中,assign 是一个关键字,用于为信号赋值
1.编写top.v:
1 | module top ( |
2.编写main.cpp:
1 |
|
3.使用如下命令:
1 | verilator --cc --exe --build -Wall --trace top.v main.cpp |
4.执行生成的Vtop可执行文件
1 | ./obj_dir/Vtop |
5.shell观察波形
1 | gtkwave wave.vcd |
1.top.v:
1 | module top ( |
2.main.cpp:
1 |
|
3.使用如下命令:
1 | verilator --cc --exe --build -Wall --trace top.v main.cpp |
4.执行生成的Vtop可执行文件
1 | ./obj_dir/Vtop |
5.shell观察波形
1 | gtkwave wave.vcd |
三、Linux入门教程
1.基本命令
find . -name “*.[c]” ———查找当前目录下的.c文件
grep “\bint i\b” a.c 查找文件中定义变量i的位置 —————-模式”\bint i\b”包含了单词边界锚点(
\b)在”int i”周围。这些锚点指定”int i”应该是一个完整的单词,而不是更大单词的一部分。wc a.c 返回该文件的行数 单词数 字符数 要求为文本文件
cp source destination 复制命令 把左边文件的内容复制到右边
2.Linux vs. Windows
1.有些简单的事Windows GUI反而做不好
比较两个文件是否相同
Linux的解决方案:
文本文件的解决方案
1
vimdiff file1 file2
非文本文件的解决方案
1
diff file1 file2
很大的文件
1
md5sum file1 file2
2.有些复杂的事Windows GUI几乎做不了
列出一个项目中所有被包含的头文件
Linux的解决方案:通过管道进行解决
1 | find . -name "*.[ch]" | xargs cat | grep "^#include" | sort | uniq |
3.工具如何运行
(1)一个重要的踪迹工具:strace
- system call strace,记录程序运行过程中的系统调用信息
- 系统调用:一个由操作系统来执行的特殊的函数调用
在Linux中,Path是一个非常重要的概念,它是用来定位系统中各种可执行文件、命令和脚本的路径。
1 | strace bash -c "PATH = 'aaa:bbb:ccc' ls" //整个命令的目的是使用strace追踪Bash shell在将PATH环境变量设置为'aaa:bbb:ccc'后执行ls命令时所发起的系统调用。 |
(2)用户与man交互
在 man 命令下进行手册的阅读时,可以使用一些快捷键和搜索命令来进行快速搜索。以下是一些建议:
使用/进行搜索:
- 在 `man` 页面中按 `/` 键,然后输入你要搜索的关键词,按回车。`man` 会定位到第一个匹配的文本。 - 按 `n` 键继续查找下一个匹配,按 `N` 键查找上一个匹配。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
### (3)强大的shell
1.通配符 * (任意长度的任意字符串) | ? (任意一个字符) | [...](集合中的任意一个字符)
2.括号扩展{...}(例:echo Hello-{a,bb,ccc}-{1,2}!)--------->
------>输出结果为:Hello-a-1! Hello-a-2! Hello-bb-1! Hello-bb-2! Hello-ccc-1! Hello-ccc-2!
### (3)使用alias为常用命令设置别名
```c
alias ls = "ls --color"
可以写入~/.bashrc文件,打开终端时生效,无需重复设置:source ~/.bashrc
(4)任务管理
1.查看任务管理器:ps aux ——-> 静态命令,只显示在命令运行时的瞬时数据。
ps是一个用于报告当前系统进程信息的命令aux选项表示以详细的方式显示所有用户的所有进程- 提供了基本的进程信息,如进程ID(PID)、CPU利用率、内存使用、启动时间等
2.top 提供了实时动态更新的系统监视器
3.htop 是 top 的增强版,提供了更直观的界面和更多功能
(5)输入输出重定向
已知Linux上的程序在运行时默认打开了3个文件,通过“文件描述符”来编号:
- 0号文件 - 标准输入(默认为当前终端)
- 1号文件 - 标准输出(默认为当前终端)
- 2号文件 - 标准错误(默认为当前终端)
1.向文件追加输出
1 | ls >> result.txt |
2.将标准错误重定向到文件
1 | ls 2> /dev/null... |
3.将标准输入重定向到文件,无需手动输入
1 | sort < result.txt |
(6)管道:工具间组合的秘诀
管道 = 一个用于连接程序间输入输出的缓冲区
xargs:一个特殊的命令,可以将标准输入转变为命令的参数
- 自制CPU主频监视器
1 | watch -n 1 "cat /proc/cpuinfo | grep MHz | awk '{print \$1 NR \$3 \$4 \$2}'" |
Linux中可执行文件为ELF文件
4.如何学习Linux
最重要的Linux命令:
1 | man |