ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux移植日记 day1

2020-03-11 09:09:08  阅读:302  来源: 互联网

标签:status 0x00000000 addr day1 nemu 64 Linux cp0 日记


基础条件回顾:
完成了一个带有段寄存器的基于MIPS的多周期CPU,现有u-boot代码以及差分测试框架,以成功运行u-boot为目标

实用工具积累:
2020-3-6:

mips-linux-gnu-objdump -d u-boot | less

——定位u-boot运行结果出错的pc、instr

交叉编译的话需要用对应的编译器,比如:aarch64-linux-gnu-objdump -d build/kernel8.elf

因为本机使用的是mips和linux-gnu的交叉编译器,所以需要使用这样的命令才能反汇编。

-d 参数表示反汇编需要执行指令的section(-D 表示反汇编全部section)

| 在linux中称为管道,可以把上一条命令的结果作为下一条命令的参数,在此处就是将反汇编的文件作为了less的参数

less 命令可以随意浏览文件, 在查看之前不会加载整个文件,进入文件后可以/something 搜索指定内容somthing

& 表示任务在后台执行
&& 表示前一条命令执行成功时,才执行后一条命令
| 表示管道,上一条命令的输出,作为下一条命令参数
|| 表示上一条命令执行失败后,才执行下一条命令

2020-3-10

Error : bfc00500: 40087801 mfc0 t0,$15,1

$pc:    0xbfc0051c   $hi:    0x00000000   $lo:    0x00000000
$ninstr: 00000000                  $instr: 40086000
$0 :0x00000000 $at:0x00000000 $v0:0x00000000 $v1:0x00000000
$a0:0x00000000 $a1:0x00000000 $a2:0x00000000 $a3:0x00000000
$t0:0x10400000 $t1:0x00000000 $t2:0x00000000 $t3:0x00000000
$t4:0x00000000 $t5:0x00000000 $t6:0x00000000 $t7:0x00000000
$s0:0x00000000 $s1:0x00000000 $s2:0x00000000 $s3:0x00000000
$s4:0x00000000 $s5:0x00000000 $s6:0x00000000 $s7:0x00000000
$t8:0x00000000 $t9:0x00000000 $k0:0x00000000 $k1:0x00000000
$gp:0x00000000 $sp:0x00000000 $fp:0x00000000 $ra:0x00000000
==============nemu status end===============
cycle 53: gpr[8]: nemu:10400000 <> dut:00000000

CP0 的 15 号寄存器: Processor Identification,主要是company和processor设计信息.

  val s0_value = Mux1H(Array(
  (cp0_addr === "b111000".U) -> base.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b1000000".U) ->  badvaddr.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b1001000".U) ->  count0.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b1001001".U)  ->  count1.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b1011000".U ) ->  compare.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b1100000".U)  ->   status.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b1101000".U )  ->  cause.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b1110000".U )  ->   epc.asTypeOf(UInt(conf.xprlen.W)),
  (cp0_addr === "b10000111".U )  ->   prid)
  ))

当初设计没有考虑Pid寄存器,直接置0了,所以现在在Mux1H()后面加上。(为什么我用二进制?好像当初switch结构一直失败报错?)后面的写如操作也要补上

Error:bfc0051c: 40086000 mfc0 t0,c0_status

==============nemu registers================
$pc:    0xbfc0051c   $hi:    0x00000000   $lo:    0x00000000
$ninstr: 00000000                  $instr: 40086000
$0 :0x00000000 $at:0x00000000 $v0:0x00000000 $v1:0x00000000
$a0:0x00000000 $a1:0x00000000 $a2:0x00000000 $a3:0x00000000
$t0:0x10400000 $t1:0x00000000 $t2:0x00000000 $t3:0x00000000
$t4:0x00000000 $t5:0x00000000 $t6:0x00000000 $t7:0x00000000
$s0:0x00000000 $s1:0x00000000 $s2:0x00000000 $s3:0x00000000
$s4:0x00000000 $s5:0x00000000 $s6:0x00000000 $s7:0x00000000
$t8:0x00000000 $t9:0x00000000 $k0:0x00000000 $k1:0x00000000
$gp:0x00000000 $sp:0x00000000 $fp:0x00000000 $ra:0x00000000
==============nemu status end===============
cycle 53: gpr[8]: nemu:10400000 <> dut:00000000

c0_status的初始值应该为10400000,之前设计的除了BEV置1其他全为0,
在这里插入图片描述按MIPS_Vol手册重新初始化,加入CU字段。
在scala语言中,class的init()方法不会默认调用(之前一直以为自动调用,所以status的初始值一直为0)

  when(reset.toBool){
    cause.init()
    status.init()
  }

Error:bfc00538: 40088000 mfc0 t0,c0_config

$pc:    0xbfc00538   $hi:    0x00000000   $lo:    0x00000000
$ninstr: 00000000                  $instr: 40088000
$0 :0x00000000 $at:0x00400004 $v0:0x00000000 $v1:0x00000000
$a0:0x00000000 $a1:0x00000000 $a2:0x00000000 $a3:0x00000000
$t0:0x80000080 $t1:0x00000000 $t2:0x00000000 $t3:0x00000000
$t4:0x00000000 $t5:0x00000000 $t6:0x00000000 $t7:0x00000000
$s0:0x00000000 $s1:0x00000000 $s2:0x00000000 $s3:0x00000000
$s4:0x00000000 $s5:0x00000000 $s6:0x00000000 $s7:0x00000000
$t8:0x00000000 $t9:0x00000000 $k0:0x00000000 $k1:0x00000000
$gp:0x00000000 $sp:0x00000000 $fp:0x00000000 $ra:0x00000000
==============nemu status end===============
cycle 104: gpr[8]: nemu:80000080 <> dut:00000000

CP0 的config寄存器之前也没加入,查询手册加入,并且按照80000080初始化赋值
在这里插入图片描述9:7位为MT位,表示MMU的类型,此处为1,即standrd TLB
在这里插入图片描述按照prid方式补充

Error bfc00544: 40088001 mfc0 t0,c0_config1

==============nemu registers================
$pc:    0xbfc00544   $hi:    0x00000000   $lo:    0x00000000
$ninstr: 00000000                  $instr: 40088001
$0 :0x00000000 $at:0x00400004 $v0:0x00000000 $v1:0x00000000
$a0:0x00000000 $a1:0x00000000 $a2:0x00000000 $a3:0x00000000
$t0:0x7e9b4d80 $t1:0x00000000 $t2:0x00000000 $t3:0x00000000
$t4:0x00000000 $t5:0x00000000 $t6:0x00000000 $t7:0x00000000
$s0:0x00000000 $s1:0x00000000 $s2:0x00000000 $s3:0x00000000
$s4:0x00000000 $s5:0x00000000 $s6:0x00000000 $s7:0x00000000
$t8:0x00000000 $t9:0x00000000 $k0:0x00000000 $k1:0x00000000
$gp:0x00000000 $sp:0x00000000 $fp:0x00000000 $ra:0x00000000
==============nemu status end===============
cycle 126: gpr[8]: nemu:7e9b4d80 <> dut:00000000

看来config1也需要加入,同上
在这里插入图片描述在这里插入图片描述config1主要规定了cache的配置参数,以及mips16/64,FPU,EJTAG等是否implemented。

其中 TLB entries 最多可支持64组.
我们来计算一下,MIPS32 processor的cache容量范围
$Cache capacity = sets per way * line size *associativity $(line_size 最高位均为reserved)
Icache=[0,6442,40961288]=[0,210,222]=[0,1kB,4MB]Icache = [0 , 64*4*2,4096*128*8] = [0,2^{10},2^{22} ] = [0,1kB,4MB]Icache=[0,64∗4∗2,4096∗128∗8]=[0,210,222]=[0,1kB,4MB]
Dcache=[0,6442,40961288]=[0,210,222]=[0,1kB,4MB]Dcache = [0 , 64*4*2,4096*128*8] = [0,2^{10},2^{22} ]= [0,1kB,4MB]Dcache=[0,64∗4∗2,4096∗128∗8]=[0,210,222]=[0,1kB,4MB]
如果line_size最高位也可以使用,那么最大值为现在的两倍.

再来看看u-boot的初始配置,根据上面的"7e9b4d80"
0 111111 010 011 011 010 011 011 0 0 0 0 0 0 0

TLB Entries I/Dcache size
64 25683 = 2^11 *3 = 6KB

到此u-boot的基本配置结束了,进入了qemu的小黑框,下一步开始处理cache和TLB相关的异常和中断

标签:status,0x00000000,addr,day1,nemu,64,Linux,cp0,日记
来源: https://blog.csdn.net/qq_40891899/article/details/104780036

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有