您尚未登录。

楼主 # 2021-06-19 18:50:12

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

研究RISCV D1芯片已经一个月有余了,中间为了方便开发,也开发了一个烧写工具xfel,为方便大家研究学习,这里编写了一个简化的裸机程序,供大家参考,实现比较简单,但该有的都有了。(从xboot精简而来,想要研究高阶功能,就去参考xboot源码树)

在DDR中运行d1-baremetal.bin,这种方式比较适合快速开发调试。借助xfel工具就可以实现。

sudo xfel ddr ddr3;sudo xfel write 0x40000000 d1-baremetal.bin;sudo xfel exec 0x40000000;

烧写d1-baremetal.bin到spi nor flash,固化程序到spi nor flash, 然后上电,自动实现初始化ddr,并自拷贝到ddr中运行。

sudo xfel spinor write 0 d1-baremetal.bin

程序正确运行后,会打印如下信息;

D1 baremetal
count = 0
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
count = 11
count = 12
count = 13
count = 14
count = 15
count = 16






点击下载: d1-baremetal.7z

https://github.com/xboot/xfel
https://github.com/xboot/xboot

离线

#1 2021-06-19 19:03:55

cube
会员
注册时间: 2021-03-11
已发帖子: 95
积分: 44.5

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

请问楼主怎么实现同一个固件,既能在ddr跑,又能在flash跑的?

离线

楼主 #2 2021-06-19 19:54:19

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

	la t0, _start
	la t1, _image_start
	LREG t1, (t1)
	beq t0, t1, _avoid

	/* Initial system jtag, uart and clock */
	call sys_jtag_init
	call sys_uart_init
	call sys_clock_init

	/* Copy ddr bin to 0x00030000 */
	la t1, _ddr_bin_start
	LREG t1, (t1)
	la t2, _ddr_bin_end
	LREG t2, (t2)
	sub a2, t2, t1
	la t1, _image_start
	LREG t1, (t1)
	la t2, _ddr_bin_start
	LREG t2, (t2)
	sub t0, t2, t1
	la a1, _start
	add a1, a1, t0
	li a0, 0x00030000
	call memcpy

	/* Initial ddr controller */
	call sys_dram_init
_avoid:
	nop
	/* Copyself to link address */
	la t0, _start
	la t1, _image_start
	LREG t1, (t1)
	beq t0, t1, 1f
	call sys_copyself
1:	nop

核心就这个地方,判断当前运行地址是否是链接地址,nor flash启动的话,肯定不是链接地址,那么就会多做很多事,初始化时钟,DDR,自拷贝等,如果是链接地址,那么就跳过这些动作,直接在DDR中运行。

离线

#3 2021-06-19 21:03:10

cube
会员
注册时间: 2021-03-11
已发帖子: 95
积分: 44.5

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

原来如此,感谢大佬解惑。

离线

#4 2021-06-20 19:04:08

微凉VeiLiang
会员
所在地: 深圳
注册时间: 2018-10-28
已发帖子: 539
积分: 488
个人网站

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

好东西,感谢xboot大佬分享裸机工程

离线

#5 2021-06-21 13:16:55

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

请问楼主,按照您的步骤,利用xfel工具直接在DDR中运行d1-baremetal.bin,串口输出运行信息,但是烧录到spi nor flash后,上电运行,串口并未输出信息,这是怎么回事呢?_20210621-1316.png

离线

#6 2021-06-21 13:27:03

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

利用spinor read 读出spi nor中的内容 发现没有并没有将.bin写进去

离线

#7 2021-06-21 13:52:39

哇酷小二
管理员
注册时间: 2020-04-22
已发帖子: 2,442
积分: 1902

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

是d1吗,你的flash型号是什么,焊好了吗?

xfel spinor 这个命令检测出是什么型号?

离线

#8 2021-06-21 13:58:49

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

是d1,应该是焊接好了,spi nor flash的信息如下:
111_20210621-1358.png
用xfel spinor这个命令输出的信息如下_20210621-1357.png

离线

#9 2021-06-21 14:02:09

哇酷小二
管理员
注册时间: 2020-04-22
已发帖子: 2,442
积分: 1902

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

March 说:

是d1,应该是焊接好了,spi nor flash的信息如下:
https://whycan.com/files/members/6619/111_20210621-1358.png
用xfel spinor这个命令输出的信息如下https://whycan.com/files/members/6619/捕获_20210621-1357.png

怪不得了,有两个选择

① 换用xfel代码里面支持的flash
② 修改 xfel代码兼容你的flash

离线

#10 2021-06-21 14:07:03

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

请问xfel支持的spi nor flash是什么型号的呢

离线

#11 2021-06-21 14:14:04

哇酷小二
管理员
注册时间: 2020-04-22
已发帖子: 2,442
积分: 1902

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

static const struct spinor_info_t spinor_infos[] = {
	{ "w25x40", 0xef3013, 512 * 1024, 4096, 1, 256, 3, OPCODE_READ, OPCODE_PROG, OPCODE_WREN, OPCODE_E4K, 0, OPCODE_E64K, 0 },
};

https://github.com/xboot/xfel/blob/master/spinor.c

看代码, 应该目前只支持 w25x40

离线

楼主 #12 2021-06-21 14:39:02

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

目前支持所有sfdp协议 nor flash,不支持sfdp协议的,就需要自己填入flash信息,w25x40是不支持sfdp的

离线

楼主 #13 2021-06-21 14:40:48

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

你这边既然能正确获取flash容量,应该是支持sfdp协议的,但还是烧不进去,有点奇怪,但可以做个测试,重新上电后,仅写入64KB,然后再读出来,看是否一致。不应该出现这种现象的。

离线

楼主 #14 2021-06-21 14:43:23

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

你在虚拟机里跑,有没有可能是虚拟机相关问题了,可以真机或者windows烧录实验下。

离线

#15 2021-06-21 14:53:14

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

我再测试测试

离线

#16 2021-06-22 11:13:27

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

请问楼主可以分享一下D1的mksunxi工具的源码吗?

离线

#17 2021-06-22 12:04:02

tigger
会员
注册时间: 2021-06-18
已发帖子: 73
积分: 37

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

March 说:

请问楼主可以分享一下D1的mksunxi工具的源码吗?

mksunxi.c

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

#if 0
static inline uint32_t __swab32(uint32_t x)
{
	return ( (x<<24) | (x>>24) | \
		((x & (uint32_t)0x0000ff00UL)<<8) | \
		((x & (uint32_t)0x00ff0000UL)>>8) );
}
#define cpu_to_le32(x)	(__swab32((uint32_t)(x)))
#define le32_to_cpu(x)	(__swab32((uint32_t)(x)))
#else
#define cpu_to_le32(x)	(x)
#define le32_to_cpu(x)	(x)
#endif

struct boot_head_t {
	uint32_t instruction;
	uint8_t magic[8];
	uint32_t checksum;
	uint32_t length;
	uint8_t spl_signature[4];
	uint32_t fel_script_address;
	uint32_t fel_uenv_length;
	uint32_t dt_name_offset;
	uint32_t reserved1;
	uint32_t boot_media;
	uint32_t string_pool[13];
};

int main (int argc, char *argv[])
{
	struct boot_head_t * h;
	FILE * fp;
	char * buffer;
	int buflen, filelen;
	uint32_t * p;
	uint32_t sum;
	int i, l, loop;
	
	if(argc != 2)
	{
		printf("Usage: mksunxi <bootloader>\n");
		return -1;
	}

	fp = fopen(argv[1], "r+b");
	if(fp == NULL)
	{
		printf("Open bootloader error\n");
		return -1;
	}
	fseek(fp, 0L, SEEK_END);
	filelen = ftell(fp);
	fseek(fp, 0L, SEEK_SET);
	
	if(filelen <= sizeof(struct boot_head_t))
	{
		fclose(fp);
		printf("The size of bootloader too small\n");
		return -1;
	}

	buflen = (filelen + 0x2000) & ~(0x2000 - 1);
	buffer = malloc(buflen);
	memset(buffer, 0, buflen);
	if(fread(buffer, 1, filelen, fp) != filelen)
	{
		printf("Can't read bootloader\n");
		free(buffer);
		fclose(fp);
		return -1;
	}

	h = (struct boot_head_t *)buffer;
	p = (uint32_t *)h;
	l = le32_to_cpu(h->length);
	h->checksum = cpu_to_le32(0x5F0A6C39);
	loop = l >> 2;
	for(i = 0, sum = 0; i < loop; i++)
		sum += le32_to_cpu(p[i]);
	h->checksum = cpu_to_le32(sum);
	
	fseek(fp, 0L, SEEK_SET);
	if(fwrite(buffer, 1, buflen, fp) != buflen)
	{
		printf("Write bootloader error\n");
		free(buffer);
		fclose(fp);
		return -1;
	}

	fclose(fp);
	printf("The bootloader head has been fixed\n");
	return 0;
}

离线

#18 2021-06-26 20:43:09

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

请问楼主,关于中断向量表这部分的汇编代码,有点不太懂,主要是vectors:csrw mscratch, sp    addi sp, sp, -(37 * REGSZ)     SREG x1, 1 * REGSZ(x2)...这部分。

离线

#19 2021-06-27 10:12:13

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

楼主,还有这个问题: https://whycan.com/t_6706.html ,有时候DDR信息能输出完整,有时候输出又不完整,很奇怪。

离线

楼主 #20 2021-06-27 10:45:14

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

March 说:

请问楼主,关于中断向量表这部分的汇编代码,有点不太懂,主要是vectors:csrw mscratch, sp    addi sp, sp, -(37 * REGSZ)     SREG x1, 1 * REGSZ(x2)...这部分。

就是中断现场保护,没什么特别的。

离线

楼主 #21 2021-06-27 10:51:03

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

March 说:

楼主,还有这个问题: https://whycan.com/t_6706.html ,有时候DDR信息能输出完整,有时候输出又不完整,很奇怪。

这个估计你哪里异常了,DDR不要初始化两次,还有要注意cache类问题,需要你自己仔细对比自己的操作。

离线

#22 2021-06-28 10:49:27

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

xboot 说:
March 说:

请问楼主,关于中断向量表这部分的汇编代码,有点不太懂,主要是vectors:csrw mscratch, sp    addi sp, sp, -(37 * REGSZ)     SREG x1, 1 * REGSZ(x2)...这部分。

就是中断现场保护,没什么特别的。

好的,谢谢楼主,请问可以提供一份关于中断的裸机程序吗(如GPIO中断),中断这部分不知道该怎么处理。谢谢。

离线

楼主 #23 2021-06-28 11:01:10

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

看xboot代码里面都有的

离线

#24 2021-06-29 22:59:27

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

参考xboot的代码,加了GPIO中断的相关代码,但是触发不了中断,不知道是哪里出了问题,求帮助。d1-baremetal.rar

离线

#25 2021-06-30 09:08:38

liao0418
会员
注册时间: 2021-06-25
已发帖子: 0
积分: 0

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

该评论内容与本帖子无关,鼓励各位坑友积极发言讨论与帖子有关的内容!

离线

  • 不通过:与技术无关

楼主 #26 2021-06-30 15:01:15

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

你这是在搞笑吗?中断控制器都没有初始化,还想触发中断

离线

#27 2021-06-30 15:16:15

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

中断控制器是PLIC吧,我初始化了啊,_20210630-1515.png 望指点

离线

楼主 #28 2021-06-30 15:25:18

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

先尝试用定时器做中断源吧,至少这个xboot是验证通过的,而且gpio中断,属于子中断,需要先开启父中断的

最近编辑记录 xboot (2021-06-30 15:26:17)

离线

#29 2021-07-02 11:27:47

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

xboot 说:

先尝试用定时器做中断源吧,至少这个xboot是验证通过的,而且gpio中断,属于子中断,需要先开启父中断的

定时器确实可以产生中断,我写的gpio中断的流程如下:_20210702-1121.png
timer的处理是类似的,您看我的gpio中断流程哪里有问题啊,不知道您说的父中断指的什么呢?

离线

楼主 #30 2021-07-02 12:53:38

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

父中段就是一个中断被多个子中段共享,gpio一般是一组对应一个父中断

离线

#31 2021-07-02 14:24:19

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

在数据手册上没有找到开启gpio父中断的相关寄存器啊

离线

#32 2021-07-02 16:16:34

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

xboot 说:

父中段就是一个中断被多个子中段共享,gpio一般是一组对应一个父中断

根据您的意思,6T$Q)F7I[)`279S`)4WCJ6S.png,这个寄存器应该控制着是gpio的子中断_20210702-1614.png,那PLIC_MIE_ REGn是控制着gpio的父中断吗?

离线

楼主 #33 2021-07-02 16:43:19

xboot
会员
注册时间: 2019-10-15
已发帖子: 370
积分: 290

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

这是中断编号,手册里有的

#define D1_IRQ_GPIOB_NS			(85)
#define D1_IRQ_GPIOC_NS			(87)
#define D1_IRQ_GPIOD_NS			(89)
#define D1_IRQ_GPIOE_NS			(91)
#define D1_IRQ_GPIOF_NS			(93)
#define D1_IRQ_GPIOG_NS			(95)

离线

#34 2021-07-06 10:11:23

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

在D1裸机程序中的sys_spinor_init函数中:
_20210706095934.png
在用户手册上并未找到SPI_CCR寄存器的相关说明啊,望指点。

离线

#35 2021-07-06 10:20:42

哇酷小二
管理员
注册时间: 2020-04-22
已发帖子: 2,442
积分: 1902

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

March 说:

在D1裸机程序中的sys_spinor_init函数中:
https://whycan.com/files/members/6619/微信图片_20210706095934.png
在用户手册上并未找到SPI_CCR寄存器的相关说明啊,望指点。

本站精华帖汇总, 各种手册在线下载,各种开源pcb工程下载
https://whycan.com/t_3019.html#p25005


d1手册确实没有 spi ccr,你找下arm系列手册,偏移应该是0x24。

离线

#36 2021-07-11 19:30:59

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

关于D1裸机的系统软件复位,在用户手册有如下寄存器描述:
_20210711-1556.png
WDOG_SOFT_RST_REG[31:16]:要想改变WDOG_SOFT_RST_REG[0]的值,需将WDOG_SOFT_RST_REG[31:16]设置为0x16AA,
WDOG_SOFT_RST_REG[0]:写1清零,那我怎么才能将WDOG_SOFT_RST_REG[0]变为1使得复位整个系统呢?
是直接将将WDOG_SOFT_RST_REG[31:16]设置为0x16AA就能使得WDOG_SOFT_RST_REG[0]变为1吗?

离线

#37 2021-07-11 19:34:06

March
会员
注册时间: 2021-05-28
已发帖子: 56
积分: 18

Re: 为方便大家研究全志RISCV D1芯片,花了点时间编写了一个精简版的裸机程序,方便大家学习参考。

找到问题在哪了,因为该寄存器的有些位是只写的,所以要一次性赋值,如下:
111_20210711-1933.png

离线

页脚

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

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