By doing this we don't need to call bios functions, we can just jsr directly to the addresses. This does mean that everytime the bios changes the bootloader has to change, but ideally all the bootloader does is load the bios and then get remapped out of memory. Any important drivers like file system can be loaded from the bootloader. This also means that the runtime functions are located in the bios for the bootloader, so the rom will have to stay mapped in until the kernel is started, at which point it will have its own runtime and the rom and bootloader are no longer needed.
52 lines
1006 B
C
52 lines
1006 B
C
#include <stdint.h>
|
|
#include <conio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "devices/board_io.h"
|
|
#include "devices/uart.h"
|
|
#include "devices/sd_card.h"
|
|
#include "devices/sd_print.h"
|
|
|
|
#define KERNEL_LOAD_ADDR 0xD000
|
|
|
|
//uint8_t buf[512];
|
|
uint8_t *buf = (uint8_t*)0x8000;
|
|
|
|
int main() {
|
|
// array to hold responses
|
|
uint8_t res[5], token;
|
|
uint32_t addr = 0x00000000;
|
|
uint16_t i;
|
|
|
|
cputs("Start\r\n");
|
|
|
|
// initialize sd card
|
|
if(SD_init() != SD_SUCCESS)
|
|
{
|
|
cputs("Error\r\n");
|
|
}
|
|
else
|
|
{
|
|
cputs("Success\r\n");
|
|
|
|
|
|
res[0] = SD_readSingleBlock(addr, buf, &token);
|
|
// if no error, print buffer
|
|
if((res[0] == 0x00) && (token == SD_START_TOKEN))
|
|
SD_printBuf(buf);
|
|
//else if error token received, print
|
|
else if(!(token & 0xF0))
|
|
{
|
|
cputs("Error\r\n");
|
|
} else {
|
|
cprintf("bad token: %x\r\n", token);
|
|
}
|
|
|
|
__asm__ ("jmp (%v)", buf);
|
|
}
|
|
|
|
while(1) ;
|
|
|
|
}
|