您尚未登录。

楼主 # 2024-11-13 17:52:58

fxx
会员
注册时间: 2023-11-13
已发帖子: 8
积分: 23

awboot数据段和代码段存在0x10000偏移

背景:

使用t113s3芯片,LcTech开发板,此板可以脱离flash,直接从USB烧录bootloader、kernel等文件并直接启动(断电后清零);

使用awboot作为bootloader,经测试可以顺利进入main函数,可以从串口打出提示信息;

bootloader烧录在0x30000,并从0x30000开始启动(xfel write 0x30000 awboot-fel.bin ; xfel exec 0x30000);

问题简述:

阅读反汇编代码,发现逻辑完全符合要求,打印前后包含测试字符串地址的寄存器未变化及修改。

测试字符串的地址0x30050传给打印函数之前,打印发现确实为0x30050,(已给打印函数增加命令:打印之前先输出待打印字符串的地址)传给打印函数后打印地址变为0x20050,并概率触发读地址错误或打印无法显示的字符。给打印函数添加新命令,接到传入地址后,地址增加0x10000,结果全部正确。

后续启动过程也存在访问地址错误的问题,怀疑与字符串显示时的地址偏移有关,所以发帖咨询:rolleyes:

下附部分反汇编代码,及link.ld文件全文。

反汇编代码说明:
前半段说明了访问字符串地址的连续性,即寄存器r0储存的确实为实际字符串ASCII值7265777169757974,即"qwertyuio",且调用函数前后没有变化,后半段为输出函数,经测试可以正常使用。

awboot-fel.elf:     file format elf32-littlearm


Disassembly of section .text:

00038000 <__spl_start>:
   38000:	ea000016 	b	38060 <__spl_start+0x60>
   38004:	4e4f4765 	cdpmi	7, 4, cr4, cr15, cr5, {3}
   38008:	3054422e 	subscc	r4, r4, lr, lsr #4
   3800c:	12345678 	eorsne	r5, r4, #120, 12	; 0x7800000
   38010:	0000950c 	andeq	r9, r0, ip, lsl #10
   38014:	00000030 	andeq	r0, r0, r0, lsr r0
   38018:	30303033 	eorscc	r3, r0, r3, lsr r0
.............................
        char *str0 = "qwertyuio";
	send_string_via_usart((int)str0);
   38b3a:	486d      	ldr	r0, [pc, #436]	; (38cf0 <main+0x200>)
   38b3c:	f000 f92c 	bl	38d98 <send_string_via_usart>
.............................
   38cf0:	0003f88d 	andeq	pc, r3, sp, lsl #17
.............................
0003f88d <.rodata.main.str1.1>:

   3f88d:	72657771 	rsbvc	r7, r5, #29622272	; 0x1c40000
   3f891:	69757974 	ldmdbvs	r5!, {r2, r4, r5, r6, r8, fp, ip, sp, lr}^
.............................
void send_string_via_usart(int a) {
   38d98:	b570      	push	{r4, r5, r6, lr}

	int tmp = a+0x18000;
   38d9a:	f500 34c0 	add.w	r4, r0, #98304	; 0x18000
	char* str = (char*)tmp;
	putint((int)str);
	for(int i = 0;i<100;i++){
		if(str[i] == '\0')break;
		sunxi_usart_putc(&USART_DBG,str[i]);
   38d9e:	4e07      	ldr	r6, [pc, #28]	; (38dbc <send_string_via_usart+0x24>)
	putint((int)str);
   38da0:	4620      	mov	r0, r4
   38da2:	f104 0564 	add.w	r5, r4, #100	; 0x64
   38da6:	f7ff ffcd 	bl	38d44 <putint>
		if(str[i] == '\0')break;
   38daa:	7821      	ldrb	r1, [r4, #0]
   38dac:	b129      	cbz	r1, 38dba <send_string_via_usart+0x22>
		sunxi_usart_putc(&USART_DBG,str[i]);
   38dae:	4630      	mov	r0, r6
	for(int i = 0;i<100;i++){
   38db0:	3401      	adds	r4, #1
		sunxi_usart_putc(&USART_DBG,str[i]);
   38db2:	f001 fadb 	bl	3a36c <sunxi_usart_putc>
	for(int i = 0;i<100;i++){
   38db6:	42ac      	cmp	r4, r5
   38db8:	d1f7      	bne.n	38daa <send_string_via_usart+0x12>
	}
}
   38dba:	bd70      	pop	{r4, r5, r6, pc}
   38dbc:	0003f588 	andeq	pc, r3, r8, lsl #11
.........................
0003a36c <sunxi_usart_putc>:
		//uint32_t usart_base = usart->base;
		uint32_t usart_base = 0x02501400;

    // 等待发送缓冲区准备好
    do {
        __asm__ volatile (
   3a36c:	4b06      	ldr	r3, [pc, #24]	; (3a388 <sunxi_usart_putc+0x1c>)
   3a36e:	6fda      	ldr	r2, [r3, #124]	; 0x7c
   3a370:	f012 0f02 	tst.w	r2, #2
            "ldr %[status], [%[base], #0x7C] \n"  // 读取状态寄存器 (偏移 0x7C)
            "tst %[status], #(1 << 1) \n"         // 检查第 1 位 (发送缓冲区是否空)
            : [status] "=r" (status)              // 输出
            : [base] "r" (usart_base)             // 输入
        );
    } while ((status & (1 << 1)) == 0);
   3a374:	0790      	lsls	r0, r2, #30
   3a376:	d5fa      	bpl.n	3a36e <sunxi_usart_putc+0x2>

    // 发送字符
    __asm__ volatile (
   3a378:	6019      	str	r1, [r3, #0]
        : [ch] "r" ((uint32_t)c), [base] "r" (usart_base)
    );

    // 等待发送完成
    do {
        __asm__ volatile (
   3a37a:	6fda      	ldr	r2, [r3, #124]	; 0x7c
   3a37c:	f012 0f01 	tst.w	r2, #1
            "ldr %[status], [%[base], #0x7C] \n"  // 读取状态寄存器 (偏移 0x7C)
            "tst %[status], #(1 << 0) \n"         // 检查第 0 位 (发送是否完成)
            : [status] "=r" (status)              // 输出
            : [base] "r" (usart_base)             // 输入
        );
    } while ((status & (1 << 0)) != 0);
   3a380:	07d2      	lsls	r2, r2, #31
   3a382:	d4fa      	bmi.n	3a37a <sunxi_usart_putc+0xe>
}
   3a384:	4770      	bx	lr
   3a386:	bf00      	nop
   3a388:	02501400 	subseq	r1, r0, #0, 8
/**
 * \file
 *
 * \brief Linker script for T113-S3 internal SRAM
 *
 * based on: Linker script for running in internal FLASH on the SAMD21G17D
 * Copyright (c) 2018 Microchip Technology Inc.
 *
 * \asf_license_start
 *
 * \page License
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the Licence at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * \asf_license_stop
 *
 */

/* This file gets parsed by the preprocessor */

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)

/* Memory Spaces Definitions */
MEMORY
{
  ram   (rwx) : ORIGIN = __RAM_BASE, LENGTH = 96K /* A1 + DSP0 IRAM + DSP0 DRAM0. 128K on boot mode, 96K on FEL mode */
}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = 0x1000; /* 4KB */

ENTRY(reset)

/* Section Definitions */
SECTIONS
{

    .text :
    {
    . = ALIGN(4);
    PROVIDE(__spl_start = .);
    *(.text .text.*)
    . = ALIGN(4);
    } > ram

    . = ALIGN(4);

    .ARM.exidx : {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } > ram

    PROVIDE(__spl_end = .);
    PROVIDE(__spl_size = __spl_end - __spl_start);

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
    } > ram

    .stack (NOLOAD):
    {
        . = ALIGN(8);
    /* SRV stack section */
        __stack_srv_start = .;
        . += STACK_SIZE;
        __stack_srv_end = .;
    } > ram

    . = ALIGN(4);
    _end = . ;
}

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn