PMON学习记录2:PMON启动流程1

PMON启动流程分析

        B站有讯为电子的详细介绍视频,连接如下,十分推荐第一次学的看一下https://www.bilibili.com/video/BV13M4y1P7H8?p=7&vd_source=7758aca909f593c8652fba5b3a94211dhttps://www.bilibili.com/video/BV13M4y1P7H8?p=7&vd_source=7758aca909f593c8652fba5b3a94211d        

        1.找到链接脚本,链接脚本决定了入口在哪

        2.分析编译命令:

        make cfg all tgt=rom ARCH=mips CROSS_COMPILE=mipsel-linux- DEBUG=-g

                第一部分:ARCH=mips CROSS_COMPILE=mipsel-linux- DEBUG=-g

                        ARCH=mips 设置了平台是mips平台

                        CROSS_COMPILE=mipsel-linux-  设置交叉编译器前缀,在编译时会替换成mipsel-linux-,之所以设置环境变量,一个是方便在这儿不用输入绝对路径,当找不到交叉编译器的时候,需要输入交叉编译器的绝对路径

                        DEBUG=-g 设置调试信息

                第二部分:make cfg all tgt=rom

                        make cfg 是配置

                        make all 

                        make tgt=rom 在Makefile.inc里可以看到,是生成的二进制文件

        3.在pmon-loongson3/zloader.ls2k文件夹下找到Makefile文件

        Makefile.ls2k:               

                TARGET=LS2K
                TARGETEL=ls2k
                export START=start.o
                MEMSIZE=128
                ZLOADER_OPTIONS=-mips3

                include Makefile.inc

        这些变量决定了在哪个路径下去编译

        4.在pmon-loongson3/zloader.ls2k文件夹下找到Makefile.inc文件

        Makefile.inc

ejtag_rom ejtag_rom1 ejtag_ram rom: clean ${START} zloader.o
         gcc  -DSTARTADDR=${GZROMSTARTADDR}  -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=mips -Umips -E -P ld.script.S  > ld.scri                
         ${LD} -T ld.script -e start -o gzrom ${START} zloader.o
         ${CROSS_COMPILE}objcopy -O binary gzrom gzrom.bin

                ejtag_rom ejtag_rom1 ejtag_ram rom: clean ${START} zloader.o
                gcc  -DSTARTADDR=${GZROMSTARTADDR}  -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=mips -Umips -E -P ld.script.S  > ld.scri                 ${LD} -T ld.script -e start -o gzrom ${START} zloader.o
                ${CROSS_COMPILE}objcopy -O binary gzrom gzrom.bin

                以上带颜色的部分都是定义了的,红色的在Makefile.ls2k里定义了,黄色的在输入指令的时候定义了,绿色的也是编译器的前缀

        下面将带颜色的部分,替换成定义的部分,更好理解这部分代码的意思

ejtag_rom ejtag_rom1 ejtag_ram rom: clean start.ozloader.o
        gcc  -DSTARTADDR=${GZROMSTARTADDR}  -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=mips -Umips -E -P ld.script.S  > ld.scri                 
        mipsel-linux-ld -T ld.script -e start -o gzrom start.o zloader.o
        mipsel-linux-objcopy -O binary gzrom gzrom.bin

               ejtag_rom ejtag_rom1 ejtag_ram rom: clean start.ozloader.o
                gcc  -DSTARTADDR=${GZROMSTARTADDR}  -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=mips -Umips -E -P ld.script.S  > ld.scri //这一段代码就是为了将ld.script.s编译生成ld.script,而这个ld.script就是链接脚本               

                mipsel-linux-ld -T ld.script -e start -o gzrom start.o zloader.o
                mipsel-linux-objcopy -O binary gzrom gzrom.bin

        

${START}:
	rm -f ../Targets/${TARGET}/compile/${TARGETEL}/${START}
	gcc  -DSTARTADDR=${ROMSTARTADDR} -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=mips -Umips -E -P ld.script.S  > ../Targets/${TARGET}/conf/ld.script
	make -C ../Targets/${TARGET}/compile/${TARGETEL}/
	cp ../Targets/${TARGET}/compile/${TARGETEL}/${START} .

        ${START}:
                    rm -f ../Targets/${TARGET}/compile/${TARGETEL}/${START}
                    gcc  -DSTARTADDR=${ROMSTARTADDR} -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=mips -Umips -E -P ld.script.S  > ../Targets/${TARGET}/conf/ld.script
                    make -C ../Targets/${TARGET}/compile/${TARGETEL}/
                    cp ../Targets/${TARGET}/compile/${TARGETEL}/${START} .

带颜色的部分,都可以在Makefile.ls2k中找到对应的定义

       将定义带入:

            ${START}:
                    rm -f ../Targets/LS2K/compile/LS2K/start.o
                    gcc  -DSTARTADDR=${ROMSTARTADDR} -DOUT_FORMAT=\"${OUT_FORMAT}\" -DOUT_ARCH=mips -Umips -E -P ld.script.S  > ../Targets/LS2K/conf/ld.script
                    make -C ../Targets/LS2K/compile/LS2K/   //使用 -C 标识会进入这个目录去执行相应的make
                    cp ../Targets/LS2K/compile/LS2K/start.o.  //执行完后,就将这个目录下的start.o复制过去了

        链接脚本:

                实际上是一个文本文件,由若干个命令组成,以分号隔开,这些命令就是命令链接器(mipsel-linux-ld)来控制链接国产

链接脚本的作用:

                我们需要分析一下这行代码:

                mipsel-linux-ld -T ld.script -e start -o gzrom start.o zloader.o

                第一部分:输入文件  start.o    zloader.o 

                第二部分:输出文件  gzrom

                第三部分:链接脚本  ld.script

                可以加将这行代码比喻成吃东西消化的国产,输入文件就是吃进去的东西,链接脚本就是消化过程,输出文件就是拉出去的东西

                我们在看看链接脚本的代码ld.script:

                        在此,将在ENTRY函数找到PMON入口_start

OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips",
              "elf32-tradlittlemips")//说明输出二进制的格式
OUTPUT_ARCH(mips)//说明输出二进制文件的平台
ENTRY(_start)//ENTRY函数的作用就是将括号中的符号值设置成入口地址,所以我们找到了PMON入口
SECTIONS
{
  . = 0xffffffff8f900000;//.可以理解成指针,指向一个地址,
                         //这个值是在Makefile.inc里决定的,GZROMSTARTADDR
  .text :    //是将所有的下面*.文件合并成.text文件
  {
    _ftext = . ;
    *(.text)
    *(.rodata)
    *(.rodata1)
    *(.reginfo)
    *(.init)
    *(.stub)
    *(.gnu.warning)
  } =0
  _etext = .;
  PROVIDE (etext = .);
  .fini : { *(.fini) } =0
  .data :
  {
    _fdata = . ;
    *(.data)
   . = ALIGN(32);
   *(.data.align32)
   . = ALIGN(64);
   *(.data.align64)
   . = ALIGN(128);
   *(.data.align128)
   . = ALIGN(4096);
   *(.data.align4096)
    CONSTRUCTORS
  }
  .data1 : { *(.data1) }
  .ctors :
  {
                __CTOR_LIST__ = .;
                LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
               *(.ctors)
                LONG(0)
                __CTOR_END__ = .;
  }
  .dtors :
  {
                __DTOR_LIST__ = .;
                LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
               *(.dtors)
                LONG(0)
                __DTOR_END__ = .;
  }
  _gp = ALIGN(16) + 0x7ff0;
  .got :
  {
    *(.got.plt) *(.got)
   }
  .sdata : { *(.sdata) }
  .lit8 : { *(.lit8) }
  .lit4 : { *(.lit4) }
  _edata = .;
  PROVIDE (edata = .);
  __bss_start = .;
  _fbss = .;
  .sbss : { *(.sbss) *(.scommon) }
  .bss :
  {
   *(.dynbss)
   *(.bss)
   . = ALIGN(32);
   *(.bss.align32)
   . = ALIGN(64);
   *(.bss.align64)
   . = ALIGN(128);
   *(.bss.align128)
   . = ALIGN(4096);
   *(.bss.align4096)
   *(COMMON)
  }
  _end = . ;
  PROVIDE (end = .);
  .stab 0 : { *(.stab) }
  .stabstr 0 : { *(.stabstr) }
  .debug 0 : { *(.debug) }
  .debug_srcinfo 0 : { *(.debug_srcinfo) }
  .debug_aranges 0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  .debug_sfnames 0 : { *(.debug_sfnames) }
  .line 0 : { *(.line) }
  .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
  .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
}

         5._start的定义

                最后在编译pmon的时候,会将start.o编译成start.s文件,可以将PMON编译信息存到一个文件中,查看编译信息,在这里就不展示了

最后在pmon-loongson3/Target/LS2K/ls2k文件夹下,可以看到生成的start.s文件内对_start的定义

 

        

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值