《自己动手写CPU》在64位WIN10搭建MIPS32编译环境的过程中遇到的问题及解决办法

虚拟机: VMware 17 pro 

环境:Ubuntu 22.04.1

不多说现在开始:

编译环境搭建好的结果就是,在一个inst_rom.S文件中写好MIPS32的汇编代码,经过编译环境,最终得到一个inst_rom.data,结束编译。inst_rom.data可以在verilog语言中,通过系统函数$readmemh导入rom中,提供给MIPS32指令集的CPU执行。

1、在Ubuntu的一个文件夹,以计算机/opt文件夹为例,点击其他位置-双击打开“计算机”-双击打开“opt”文件夹-鼠标右击-在终端打开(作为新手,opt文件夹里面应该是空的):

2、新建 inst_rom.S文件

在终端输入:

su

       (输入一个命令后按一下enter,接下来每条命令都enter)

然后输入Ubuntu密码(密码不会显示,输入完后enter),这个是获取root权限的过程,没有获取权限,做不了很多事。

在终端中输入         

touch inst_rom.S

3、写 touch inst_rom.S 文件

在终端中,点击最小化

此时,./opt 文件夹下应该有一个 inst_rom.S,但这个时候你直接双击进去发现可能是只读,这个时候有两个办法,一个是在终端输入

sudo nautilus

,可能会要求输入密码,然后进入拥有root权限的文件夹,这个时候再修改inst_rom.S就没问题了。另一个方法是 在终端输入

sudo chmod 777 inst_rom.S

,通过修改inst_rom.S文件的读写权限, 这个时候就可以修改 inst_rom.S了。

再inst_rom.S文件写入《自己动手写CPU》中的代码例子:

.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

保存退出。

4、安装GNU工具链

在终端输入

mips-linux-gnu-gcc -v

根据提示安装工具链 ,各式如下,XXX填入提示的工具包

sudo apt-get install XXX

 5、调用包进行编译

根据inst_rom.S 得到 inst_rom.o

mips-linux-gnu-as -mips32 inst_rom.S -o inst_rom.o

在opt文件夹中发现多了一个inst_rom.o文件。

6、调用包进行链接

在此之前,先建立一个ram.ld 文件

touch ram.ld

在ram.ld写入,该代码来自《自己动手写CPU》,如果文件只读,参见第3步的两种方法。

MEMORY
        {      
        ram(RW)    : ORIGIN = 0x00000000, LENGTH = 0x00001000
        }
SECTIONS
{
	  /*
	  For some reason the linker script can't see the _reset_vector symbol 
	  (even if we declare it global), so we explicitly set it. */
	.text :
        {
        *(.text)
        } > ram

        .data :
        {
        *(.data)
        } > ram
        .bss :
        {
        *(.bss)
        } > ram
        .stack  ALIGN(0x10) (NOLOAD):
        {
        *(.stack)
        _ram_end = .;
        } > ram
}
ENTRY (_start)

,保存ram.ld,然后在终端执行下列代码,对inst_rom.o文件进行链接:

mips-linux-gnu-ld -T ram.ld inst_rom.o -o inst_rom.om

7、格式文件转换

在终端输入

mips-linux-gnu-objcopy -O binary inst_rom.om inst_rom.bin

,得到inst_rom.bin文件,此时里面的就是机器码的二进制形式,为了得到rom初始化文件.data,再进行最后一步转换。

8、bin转换成data

在终端输入下列代码,建立一个perl文件

touch Bin2Mem.pl

在Bin2Mem.pl里面输入下列代码,然后保存,文件只读详见第3步。   代码改写自gcvideo/bin2mem.pl at main · ikorb/gcvideo · GitHub

#!/usr/bin/env perl

use warnings;
use strict;
use feature ':5.10';

if (scalar(@ARGV) != 2) {
    say "Usage: $0 in.bin out.data\n";
    exit 1;
}

open IN,"<",$ARGV[0] or die "Can't open $ARGV[0]: $!";
open OUT,">",$ARGV[1] or die "Can't open $ARGV[1]: $!";

binmode IN;
binmode OUT;

my $buffer;

read(IN,$buffer,(-s $ARGV[0])) or die "Can't read from input: $!";

# pad to word size
while ((length($buffer) % 4) != 0) {
    $buffer .= chr(0);
}

# swap endianness of words
#$buffer = pack("N*", unpack("V*", $buffer));

# swap nibbles
#$buffer = pack("H*", unpack("h*", $buffer));

my $address = 0;
while (length($buffer) > 0) {
    #printf OUT "@%08X", $address;

    my $str = substr($buffer, 0, 4 );
    for (my $i=0; $i<length($str); $i++) {
	printf OUT "%02X", ord(substr($str, $i, 1));
    }
    print OUT "\n";

    $buffer = substr($buffer, length($str));
    #$address += 16;
}

close IN;
close OUT;

然后输入下列代码,进行格式转换,

./Bin2Mem.pl inst_rom.bin inst_rom.data

如果提示bash Bin2Mem.pl :权限不够,就在终端输入下列指令,没有就略过这一步:

chmod a+x ./Bin2Mem.pl

结果得到最后的inst_rom.data文件,此文件可以初始化rom。下图是结果inst_rom.data

这一个流程就完成任务了,之后修改inst_rom.S文件,再依次执行一下四条代码,inst_rom.data就是相应的目标文件了。

mips-linux-gnu-as -mips32 -EB inst_rom.S -o inst_rom.o
mips-linux-gnu-ld -T ram.ld inst_rom.o -o inst_rom.om
mips-linux-gnu-objcopy -O binary inst_rom.om inst_rom.bin
./Bin2Mem.pl inst_rom.bin inst_rom.data

 ,但是笔者嫌麻烦,根据《自己动手写CPU》,这里提供的代码,修改自书本提供的Makefile文件。

9、建立Makefile文件

终端输入

touch Makefile

建立Makefile文件,在里面写入,,,根据《自己动手写CPU》,这里提供的代码,修改自书本提供的Makefile文件。

ifndef CROSS_COMPILE
	CROSS_COMPILE = mips-linux-gnu-
endif
CC = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld

OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump

OBJECTS = inst_rom.o
export CROSS_COMPILE
all:inst_rom.data inst_rom.om inst_rom.o inst_rom.bin inst_rom.asm

%.o:%.S
	$(CC) -mips32 -EB $< -o $@

inst_rom.om:ram.ld $(OBJECTS) 
	$(LD) -T ram.ld $(OBJECTS) -o $@

inst_rom.bin:inst_rom.om
	$(OBJCOPY) -O binary $< $@

inst_rom.asm:inst_rom.om
	$(OBJDUMP) -D $< >$@

inst_rom.data:inst_rom.bin
	./Bin2Mem.pl $< $@

clean:
	rm -f *.o *.om *.bin *.data

,保存,然后在终端输入

sudo apt install make

,就完成了,以后再修改inst_rom.S文件,只需在终端输入

make all

一次完成四条指令,得到修改后的inst_rom.data,如果没有修改,会提示 all 没有事情可做。

除此之外,Makefile中还添加了一部分代码,可以根据inst_rom.om文件反汇编产生相对于的汇编文件 inst_rom.asm。

10、写在最后

a,在操作的过程中,可能会面临权限不够的困境,则在执行该条代码之前执行 su ,然后输入密码获取root权限,或者是在执行代码的前插入 sudo ,比如 sudo make all

b,有时候会出现找不到文件,无法打开之类的问题,那就对相应的文件,执行

chmod 777 XXX

 ,XXX 改成相应的文件名及后缀,修改相应文件的权限,尤其是Bin2Mem.pl,ram.lm,Makefile ,inst_rom.S这些文件。

c,笔者本身是根据《自己动手写CPU》的书籍内容照葫芦画瓢来的,

下载了虚拟机VMware 17 Pro

安装 Ubuntu 22.04.1

等了老半天才完成注册账号,然后苦于安装vmware tools ,各种查找CSDN回答,各种参考,多次安装,才实现了共享文件夹,其中的困难重重,如果有缘我会更新我踩过的这些坑。

实现共享文件夹了之后,好不容易可以正式开始了,导入了《自己动手写CPU》提供的工具链文件后,照样子安装之后,发现工具包无法使用,仔细一查,有博主说工具包根据32位运行,但是我的电脑是64位,ubuntu也是,心态崩了,然后才从一篇知乎上找到另有其他gnu工具包(,知乎源回答Ubuntu中搭建MIPS编译环境 - 知乎 (zhihu.com)。)

照着来,发现到Bin2Mem.exe的时候又是出了问题,于是爬到网上,根据

risc-v MCU 的研究 - eddsos的日志 - EETOP 创芯网论坛 (原名:电子顶级开发网) -

的答主的说法,我找到了github(gcvideo/bin2mem.pl at main · ikorb/gcvideo · GitHub)的一段类似地perl代码,进行修改得到Bin2Mem.pl,使用方法有小小的改动。

然后再最后的整合,我又对《自己动手写CPU》提供的Makefile文件做出一些小改动,终于完成任务。

d,说说感受,本身答主没有接触过虚拟机,没有接触过linux,更没有了解linux的操作,各种东西都是一步步摸着石头过河完成的,不会perl、Makefile,对对着看修改参数,不懂linux操作,就网上搜着教程自己感悟,也是如此,我提供的思路和代码,或许在众多大佬面前是如此的幼稚,但是还请原谅,毕竟这修改自某个小白之手。

e,因为我写这篇文章,默认的读者是有阅读过《自己动手写CPU》的,所以很多步骤究竟是为什么我就不详细说明了,而且很多CSDN文章也有相似的内容。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值