此博客为个人博客,不涉及商业用途,仅提供学习参考,内容均来自个人原创以及互联网转载和摘录。
此博客上带有原创标识的文章、图片、文件等,未经本人允许,不得用于商业用途以及传统媒体。
本文首发于优快云,其他网站均为转载。网络媒体或个人转载请注明出处和链接,否则属于侵权行为。
原博客链接:https://blog.youkuaiyun.com/qq_38305370
原博主昵称:城外南风起
————————————————
安装GNU工具链
输入以下代码检测是否安装成功。
mips-linux-gnu-gcc -v
没有的话会有相应的安装命令提示,根据提示安装即可。
编译
新建文件夹tinymips,作为工作文件夹。在该文件夹中打开terminal。
使用以下命令新建文件inst_rom.s。
touch inst_rom.s
在inst_rom.s输入以下测试程序。
.org 0x0
.global _start
.set noat
_start:
ori $1, $0, 0x1100 # $1 = $0 | 0x1100 = 0x1100
ori $2, $0, 0x0020 # $2 = $0 | 0x0020 = 0x0020
ori $3, $0, 0xff00 # $3 = $0 | 0xff00 = 0xff00
ori $4, $0, 0xffff # $4 = $0 | 0xffff = 0xffff
使用以下命令进行编译。其中添加了” -mips32"选项,表示按照MIPS32指令集架构进行编译。
mips-linux-gnu-as -mips32 inst_rom.s -o inst_rom.o
上述命令会得到文件inst_rom.o,是一个ELF文件。
链接
通过编译得到了一个ELF文件,但这个文件还不能执行,衙要通过链接转化为可执行文件, 然后才能执行。
使用touch命令新建一个Document作为链接描述脚本, 文件名为ram.Id,内容如下。
MEMORY
{
ram : ORIGIN = 0x00000000, LENGTH = 0x00001000
}
SECTIONS
{
.text :
{
*(.text)
} > ram
.data :
{
*(.data)
} > ram
.bss :
{
* (.bss)
} > ram
}
ENTRY (_start)
现在就可以使用链接器了,在终端输入以下代码进行链接,得到链接后的文件inst_rom.om。
mips-linux-gnu-ld -T ram.ld inst_rom.o -o inst_rom.om
得到ROM初始化文件
inst_rom.om是一个ELF格式的可执行文件,与我们希望的指令存储器ROM初始化文件inst_rom.data 的格式有很大区别,需要进行格式转化。
利用以下命令可以将inst_rom.om转化为二进制(Binary)形式。
mips-linux-gnu-objcopy -O binary inst_rom.om inst_ron.bin
得到inst_rom.bin文件。将Bin2Mem.exe拷贝至工作文件夹,利用Bin2Mem.exe程序将其转为inst_rom.data文件,命令如下:
./Bin2Mem.exe -f inst_rom.bin -o inst_rom.data
下面给出Bin2Mem.c代码,来自@CherryYang~:Linux点点滴滴(二):在Linux上安装GNU工具链并进行编译:
#include <stdlib.h>
#include <stdio.h>
char *option_invalid = NULL;
char *option_file_in = NULL;
char *option_file_out = NULL;
FILE *file_in_descriptor = NULL;
FILE *file_out_descriptor = NULL;
void exception_handler(int code) {
switch (code) {
case 0:
break;
case 10001:
printf("Error (10001): No option recognized.\n");
printf("Please specify at least one valid option.\n");
break;
case 10002:
printf("Error (10002): Invalid option: %s\n", option_invalid);
break;
case 10003:
printf("Error (10003): No input Binary file specified.\n");
break;
case 10004:
printf("Error (10004): Cannot open file: %s\n", option_file_in);
break;
case 10005:
printf("Error (10005): Cannot create file: %s\n", option_file_out);
break;
default:
break;
}
if (file_in_descriptor != NULL) {
fclose(file_in_descriptor);
}
if (file_out_descriptor != NULL) {
fclose(file_out_descriptor);
}
exit(0);
}
int main(int argc, char **argv) {
int i=0,j=0;
unsigned char temp1,temp2,temp3,temp4;
unsigned int option_flag = 0;
while (argc > 0) {
if (**argv == '-') {
(*argv) ++;
switch (**argv) {
case 'f':
option_flag |= 0x4;
argv ++;
option_file_in = *argv;
argc --;
break;
case 'o':
option_flag |= 0x8;
argv ++;
option_file_out = *argv;
argc --;
break;
default:
option_flag |= 0x1;
(*argv) --;
option_invalid = *argv;
break;
}
}
argv ++;
argc --;
}
file_in_descriptor = fopen(option_file_in, "rb");
if (file_in_descriptor == NULL) {
exception_handler(10004);
}
file_out_descriptor = fopen(option_file_out, "w");
if (file_out_descriptor == NULL) {
exception_handler(10005);
}
while (!feof(file_in_descriptor)) {
fscanf(file_in_descriptor, "%c", &temp1);
fscanf(file_in_descriptor, "%c", &temp2);
fscanf(file_in_descriptor, "%c", &temp3);
fscanf(file_in_descriptor, "%c", &temp4);
if(!feof(file_in_descriptor)) {
fprintf(file_out_descriptor, "%02x", temp1);
fprintf(file_out_descriptor, "%02x", temp2);
fprintf(file_out_descriptor, "%02x", temp3);
fprintf(file_out_descriptor, "%02x", temp4);
fprintf(file_out_descriptor, "\n");
}
}
exception_handler(0);
return 0;
}
编写Makefile文件
为了得到指令存储器初始化文件,我们需要输入4条命令, 点麻烦,最好只输入一条命令就可以了,这需要使用Makefile 文件。
在汇编程序inst_rom.s所在目录下新建一个Document,文件名为Makefile,内容如下。
ifndef CROSS_COMPILE
CROSS_COMPILE = mips-linux-gnu-
endif
CC = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJECTS = inst_rom.o
export CROSS_COMPILE
all: inst_rom.data
%.o:%.s
$(CC) -mips32 $< -o $@
inst_rom.om: ram.ld $(OBJECTS)
$(LD) -T ram.ld $(OBJECTS) -o $@
inst_rom.bin: inst_rom.om
$(OBJCOPY) -O binary $< $@
inst_rom.data: inst_rom.bin
./Bin2Mem.exe -f $< -o $@
clean:
rm -f *.o *.om *.bin *.data
接下来,在终端使用以下命令安装make工具。
sudo apt install make
输入用户密码即可完成安装。
接着使用make all命令就可以通过makefile文件完成前面的四个步骤。
makefile可以通过@haoel:跟我一起写 Makefile学习。
Mecklenburg的书《MANAGING PROJECTS WITH GNU MAKE》更好。
参考
1.雷思磊著.自己动手写CPU[M].电子工业出版社,2014.
2.CherryYang~: Linux点点滴滴(二):在Linux上安装GNU工具链并进行编译
https://blog.youkuaiyun.com/qq_42650988/article/details/103532682
————————————————
感谢您的阅读,如果您有收获,请给我一个三连吧!
如果您觉得这还不够,可以点击 打赏 按钮,告诉我: 你币有了!