RISCV基础开发(十八)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2021年8月22日10:52:54 评论 752

QEMU OpenSBI 裸机开发之格式化打印

格式化打印代码也跟之前的基本一样,就是将字符输出函数从原来的直接操作16550寄存器改为通过SBI接口进行字符输出,其他的都一样,将printf函数定义在printf.c中,如下所示。

#include <stdarg.h>
#include "sbi.h"

static void uart_putc(char c)
{
    sbi_console_putchar(c);
}

//printf functions
static char digits[] = "0123456789abcdef";

static void print_int(int xx, int base, int sign)
{
    char buf[16];
    int i;
    unsigned int x;

    if(sign && (sign = xx < 0))
        x = -xx;
    else
        x = xx;

    i = 0;
    do {
        buf[i++] = digits[x % base];
    } while((x /= base) != 0);

    if(sign)
        buf[i++] = '-';

    while(--i >= 0)
        uart_putc(buf[i]);
}

static void print_ptr(unsigned long x)
{
    int i;
    uart_putc('0');
    uart_putc('x');

    for (i = 0; i < (sizeof(unsigned long) * 2); i++, x <<= 4)
        uart_putc(digits[x >> (sizeof(unsigned long) * 8 - 4)]);
}

// Print to the console. only understands %d, %x, %p, %s.
void printf(char *fmt, ...)
{
    va_list ap;
    int i, c;
    char *s;

    if (fmt == 0)
        return;

    va_start(ap, fmt);
    for(i = 0; (c = fmt[i] & 0xff) != 0; i++) {
        if(c != '%'){
            uart_putc(c);
            continue;
        }

        c = fmt[++i] & 0xff;
        if(c == 0)
            break;

        switch(c){
        case 'd':
            print_int(va_arg(ap, int), 10, 1);
            break;

        case 'x':
            print_int(va_arg(ap, int), 16, 1);
            break;

        case 'p':
            print_ptr(va_arg(ap, unsigned long));
            break;

        case 's':
            if((s = va_arg(ap, char*)) == 0)
                s = "(null)";

            for(; *s; s++)
                uart_putc(*s);
            break;

        case '%':
            uart_putc('%');
            break;

        default:
            // Print unknown % sequence to draw attention.
            uart_putc('%');
            uart_putc(c);
            break;
        }
    }
}

将“start.c”中的打印换成printf,如下所示。

#include "printf.h"

void start(void)
{
    printf("%s %d.\r\n", __func__, __LINE__);
}

在命令行执行“make qemu”,可以在最后看到打印的函数名以及行号信息,如下所示。

gewenbin@gewenbin-virtual-machine:~/Desktop/qemu_test/lesson13$ make qemu
riscv64-unknown-elf-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie   -c -o printf.o printf.c
riscv64-unknown-elf-ld -z max-page-size=4096 -T kernel.ld -o kernelimage entry.o start.o printf.o 
riscv64-unknown-elf-objdump -S kernelimage > kernel.asm
riscv64-unknown-elf-objdump -t kernelimage | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > kernel.sym
qemu-system-riscv64 -machine virt -bios fw_jump.elf -kernel kernelimage -m 128M -smp 1 -nographic

OpenSBI v0.8-81-g7dcb1e1
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name             : riscv-virtio,qemu
Platform Features         : timer,mfdeleg
Platform HART Count       : 1
Firmware Base             : 0x80000000
Firmware Size             : 112 KB
Runtime SBI Version       : 0.2

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000080000000-0x000000008001ffff ()
Domain0 Region01          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address      : 0x0000000080200000
Domain0 Next Arg1         : 0x0000000082200000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes

Boot HART ID              : 0
Boot HART Domain          : root
Boot HART ISA             : rv64imafdcsu
Boot HART Features        : scounteren,mcounteren,time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count      : 0
Boot HART MHPM Count      : 0
Boot HART MIDELEG         : 0x0000000000000222
Boot HART MEDELEG         : 0x000000000000b109
start 5.

工程源码:链接:https://pan.baidu.com/s/1TnTYr7mywdKj5bxpdmWnyA,提取码:q772,见lesson13。

gewenbin
  • 本文由 发表于 2021年8月22日10:52:54
  • 转载请务必保留本文链接:http://www.databusworld.cn/10555.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: