裸机编程之helloworld -PMON引导篇
本帖最后由 佐须之男 于 2017-11-28 16:18 编辑众所周知,pmon可以引导elf程序,所以理论上不需要用汇编就可以编写裸机程序。
准备工作:
1.配置交叉编译工具,步骤略。
2.配置tftp server,步骤略。
背景知识介绍:
1.龙芯启动后的运行的代码位置是:0xbfc00000 (spi引导模式)。
2.pmon引导的地址是0x80200000(大部分bootloader都是此地址)。
3.gcc编译好的程序不能直接运行,因为内存映射不同,所以需要用ld工具重新映射地址空间。
教程部分:
1.从http://git.oschina.net/ForgotFun/loongson下载hello的代码,cd hello执行make,makefile会自动拷贝hello到/tftpboot目录
2.配置tftp server和设置本机的IP地址为 192.168.1.2
3.设置pmon的环境变量,ctrl+c 进入pmon的命令模式,执行
set syn0.ipaddr 192.168.1.1
set al tftp://192.168.1.2/a.out
假如出现env环境下,你的mac地址为IP地址是设置不了的,这种情况会出现在自己编译的pmon上,解决方案是执行
set ethaddr ea:8e:10:a6:ec:93
4.按主板上的复位键,运行程序,出现如下信息,说明成功了
Loading file: tftp://192.168.1.2/a.out (elf)
0x80200000/4112 + 0x80201010/4080(z) + 15 syms/
Entry address is 80200008
g root=/dev/hda1 console=tty
zero at v0 v1 a0 a1 a2 a3
00000000 00000000 00000000 00000000 00000003 a10ffd18 a10ffd28 8009b900
t0 t1 t2 t3 t4 t5 t6 t7
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
s0 s1 s2 s3 s4 s5 s6 s7
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
t8 t9 k0 k1 gp sp s8 ra
00000000 00000000 00000000 00000000 00000000 a10ffcf8 00000000 8005be30
Hello! This is the 'hello' program!
It was invoked with:
Arg0: g
Arg1: root=/dev/hda1
Arg2: console=tty
我觉得重点应该是怎么实现重映射的,下面把楼主git中的Makefile和ld.script部分内容贴上来:lol
Makefile内容如下
CROSS_COMPILE =mipsel-linux-
#
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
SIZE = $(CROSS_COMPILE)size
hello: hello.c
${CC} -G 0 -O2-fno-pic -mno-abicalls -fno-builtin -nostdinc -mips3 -Ttext=0xffffffff80200000 -N -o hello hello.c -nostdlib -e main -Wl,-m -Wl,elf32ltsmip -T ld.script
cp hello /tftpboot/a.out
ld.script内容如下
OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradbigmips",
"elf32-tradlittlemips")
OUTPUT_ARCH(mips)
ENTRY(_start)
SECTIONS
{
. = 0xffffffff81000000;
.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) }
}
为楼主点赞! 为楼主点赞+1 不错 有人来研究PMON了,很多初学者的福音啊。 顶楼主!!
页:
[1]