OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /eco32/tags/eco32-0.26/disk/tools/mkmboot
    from Rev 261 to Rev 270
    Reverse comparison

Rev 261 → Rev 270

/stage2/mboot.c
0,0 → 1,273
/*
* mboot.c -- the master bootstrap (boot manager)
*/
 
 
#include "stdarg.h"
#include "biolib.h"
 
 
#define DEFAULT_PARTITION "" /* default boot partition number */
 
#define LOAD_ADDR 0xC0010000
 
#define LINE_SIZE 80
#define SECTOR_SIZE 512
#define NPE (SECTOR_SIZE / sizeof(PartEntry))
#define DESCR_SIZE 20
 
 
unsigned int bootDisk = 0; /* gets loaded by previous stage */
unsigned int startSector = 0; /* gets loaded by previous stage */
unsigned int numSectors = 0; /* gets loaded by previous stage */
 
 
typedef struct {
unsigned int type;
unsigned int start;
unsigned int size;
char descr[DESCR_SIZE];
} PartEntry;
 
PartEntry ptr[NPE];
 
 
int strlen(char *str) {
int i;
 
i = 0;
while (*str++ != '\0') {
i++;
}
return i;
}
 
 
void strcpy(char *dst, char *src) {
while ((*dst++ = *src++) != '\0') ;
}
 
 
char getchar(void) {
return getc();
}
 
 
void putchar(char c) {
if (c == '\n') {
putchar('\r');
}
putc(c);
}
 
 
void puts(char *s) {
char c;
 
while ((c = *s++) != '\0') {
putchar(c);
}
}
 
 
void getline(char *prompt, char *line, int n) {
int i;
char c;
 
puts(prompt);
puts(line);
i = strlen(line);
while (i < n - 1) {
c = getchar();
if (c >= ' ' && c < 0x7F) {
putchar(c);
line[i] = c;
i++;
} else
if (c == '\r') {
putchar('\n');
line[i] = '\0';
i = n - 1;
} else
if (c == '\b' || c == 0x7F) {
if (i > 0) {
putchar('\b');
putchar(' ');
putchar('\b');
i--;
}
}
}
line[n - 1] = '\0';
}
 
 
int countPrintn(int n) {
int a;
int res;
 
res = 0;
if (n < 0) {
res++;
n = -n;
}
a = n / 10;
if (a != 0) {
res += countPrintn(a);
}
return res + 1;
}
 
 
void printn(int n) {
int a;
 
if (n < 0) {
putchar('-');
n = -n;
}
a = n / 10;
if (a != 0) {
printn(a);
}
putchar(n % 10 + '0');
}
 
 
void printf(char *fmt, ...) {
va_list ap;
char c;
int n;
unsigned int u;
char *s;
char filler;
int width, count, i;
 
va_start(ap, fmt);
while (1) {
while ((c = *fmt++) != '%') {
if (c == '\0') {
va_end(ap);
return;
}
putchar(c);
}
c = *fmt++;
if (c == '0') {
filler = '0';
c = *fmt++;
} else {
filler = ' ';
}
width = 0;
if (c >= '0' && c <= '9') {
width = c - '0';
c = *fmt++;
}
if (c == 'd') {
n = va_arg(ap, int);
if (width > 0) {
count = countPrintn(n);
for (i = 0; i < width - count; i++) {
putchar(filler);
}
}
printn(n);
} else
if (c == 's') {
s = va_arg(ap, char *);
puts(s);
} else
if (c == 'c') {
c = va_arg(ap, char);
putchar(c);
} else {
putchar(c);
}
}
}
 
 
void halt(void) {
printf("bootstrap halted\n");
while (1) ;
}
 
 
void readDisk(unsigned int sector, unsigned char *buffer, int count) {
int result;
 
if (sector + count > numSectors) {
printf("sector number exceeds disk or partition size\n");
halt();
}
result = rwscts(bootDisk, 'r', sector + startSector,
(unsigned int) buffer & 0x3FFFFFFF, count);
if (result != 0) {
printf("disk read error\n");
halt();
}
}
 
 
unsigned int entryPoint; /* where to continue from main() */
 
 
int main(void) {
int i;
char line[LINE_SIZE];
char *p;
int part;
 
printf("Bootstrap manager executing...\n");
strcpy(line, DEFAULT_PARTITION);
readDisk(1, (unsigned char *) ptr, 1);
while (1) {
printf("\nPartitions:\n");
printf(" # | b | description\n");
printf("---+---+----------------------\n");
for (i = 0; i < NPE; i++) {
if (ptr[i].type != 0) {
printf("%2d | %s | %s\n",
i, ptr[i].type & 0x80000000 ? "*" : " ", ptr[i].descr);
}
}
getline("\nBoot partition #: ", line, LINE_SIZE);
part = 0;
if (line[0] == '\0') {
continue;
}
p = line;
while (*p >= '0' && *p <= '9') {
part = part * 10 + (*p - '0');
p++;
}
if (*p != '\0' || part < 0 || part > 15) {
printf("illegal partition number\n");
continue;
}
if ((ptr[part].type & 0x7FFFFFFF) == 0) {
printf("partition %d does not contain a file system\n", part);
continue;
}
if ((ptr[part].type & 0x80000000) == 0) {
printf("partition %d is not bootable\n", part);
continue;
}
/* load boot sector of selected partition */
readDisk(ptr[part].start, (unsigned char *) LOAD_ADDR, 1);
/* check for signature */
if ((*((unsigned char *) LOAD_ADDR + SECTOR_SIZE - 2) != 0x55) ||
(*((unsigned char *) LOAD_ADDR + SECTOR_SIZE - 1) != 0xAA)) {
printf("boot sector of partition %d has no signature\n", part);
continue;
}
/* we have a valid boot sector, leave loop */
break;
}
/* boot manager finished, now go executing loaded boot sector */
startSector = ptr[part].start;
numSectors = ptr[part].size;
entryPoint = LOAD_ADDR;
return 0;
}
/stage2/biolib.s
0,0 → 1,26
;
; biolib.s -- basic I/O library
;
 
.set cin,0xC0000018
.set cout,0xC0000020
.set dskio,0xC0000028
 
.export getc
.export putc
.export rwscts
 
.code
.align 4
 
getc:
add $8,$0,cin
jr $8
 
putc:
add $8,$0,cout
jr $8
 
rwscts:
add $8,$0,dskio
jr $8
/stage2/c0.s
0,0 → 1,59
;
; c0.s -- startup code and begin-of-segment labels
;
 
.import main
 
.import _ecode
.import _edata
.import _ebss
 
.export _bcode
.export _bdata
.export _bbss
 
.import bootDisk
.import startSector
.import numSectors
.import entryPoint
 
.code
_bcode:
 
start:
add $10,$0,_bdata ; copy data segment
add $8,$0,_edata
sub $9,$8,$10
add $9,$9,_ecode
j cpytest
cpyloop:
ldw $11,$9,0
stw $11,$8,0
cpytest:
sub $8,$8,4
sub $9,$9,4
bgeu $8,$10,cpyloop
add $8,$0,_bbss ; clear bss segment
add $9,$0,_ebss
j clrtest
clrloop:
stw $0,$8,0
add $8,$8,4
clrtest:
bltu $8,$9,clrloop
add $29,$0,0xC0020000 ; setup stack
stw $16,$0,bootDisk ; make arguments available
stw $17,$0,startSector
stw $18,$0,numSectors
jal main ; call 'main' function
ldw $16,$0,bootDisk ; setup arguments for next stage
ldw $17,$0,startSector
ldw $18,$0,numSectors
ldw $31,$0,entryPoint ; jump to loaded program
jr $31
 
.data
_bdata:
 
.bss
_bbss:
/stage2/Makefile
0,0 → 1,26
#
# Makefile to build the master bootstrap (boot manager)
#
 
BUILD = ../../../../build
 
all: mboot.bin
 
mboot.bin: c0.o mboot.o biolib.o c1.o
$(BUILD)/bin/ld -h -rc 0xC0011000 -o mboot.bin \
c0.o mboot.o biolib.o c1.o
 
c0.o: c0.s
$(BUILD)/bin/as -o c0.o c0.s
 
mboot.o: mboot.c
$(BUILD)/bin/lcc -A -c -o mboot.o mboot.c
 
biolib.o: biolib.s
$(BUILD)/bin/as -o biolib.o biolib.s
 
c1.o: c1.s
$(BUILD)/bin/as -o c1.o c1.s
 
clean:
rm -f *~ c0.o mboot.o biolib.o c1.o mboot.bin
/stage2/c1.s
0,0 → 1,19
;
; c1.s -- end-of-segment labels
;
 
.export _ecode
.export _edata
.export _ebss
 
.code
.align 4
_ecode:
 
.data
.align 4
_edata:
 
.bss
.align 4
_ebss:
/stage2/biolib.h
0,0 → 1,15
/*
* biolib.h -- basic I/O library
*/
 
 
#ifndef _BIOLIB_H_
#define _BIOLIB_H_
 
 
char getc(void);
void putc(char c);
int rwscts(int dskno, int cmd, int sector, int addr, int count);
 
 
#endif /* _BIOLIB_H_ */
/stage2/stdarg.h
0,0 → 1,41
/*
* stdarg.h -- variable argument lists
*/
 
 
#ifndef _STDARG_H_
#define _STDARG_H_
 
 
typedef char *va_list;
 
 
static float __va_arg_tmp;
 
 
#define va_start(list, start) \
((void)((list) = (sizeof(start)<4 ? \
(char *)((int *)&(start)+1) : (char *)(&(start)+1))))
 
#define __va_arg(list, mode, n) \
(__typecode(mode)==1 && sizeof(mode)==4 ? \
(__va_arg_tmp = *(double *)(&(list += \
((sizeof(double)+n)&~n))[-(int)((sizeof(double)+n)&~n)]), \
*(mode *)&__va_arg_tmp) : \
*(mode *)(&(list += \
((sizeof(mode)+n)&~n))[-(int)((sizeof(mode)+n)&~n)]))
 
#define _bigendian_va_arg(list, mode, n) \
(sizeof(mode)==1 ? *(mode *)(&(list += 4)[-1]) : \
sizeof(mode)==2 ? *(mode *)(&(list += 4)[-2]) : \
__va_arg(list, mode, n))
 
#define va_end(list) ((void)0)
 
#define va_arg(list, mode) \
(sizeof(mode)==8 ? \
*(mode *)(&(list = (char*)(((int)list + 15)&~7U))[-8]) : \
_bigendian_va_arg(list, mode, 3U))
 
 
#endif /* _STDARG_H_ */
/stage1/mbr.s
0,0 → 1,111
;
; mbr.s -- the master boot record
;
 
; Runtime environment:
;
; This code must be loaded and started at 0xC0010000.
; It allocates a stack from 0xC0011000 downwards. So
; it must run within 4K (code + data + stack).
;
; This code expects the disk number of the boot disk
; in $16, the start sector of the disk or partition
; to be booted in $17 and its size in $18.
;
; The boot manager, which is loaded by this code,
; must be in standalone (headerless) executable
; format, stored at absolute disk sectors 2..31,
; and gets loaded and started at 0xC0011000.
 
.set stacktop,0xC0011000 ; top of stack
.set loadaddr,0xC0011000 ; where to load the boot manager
 
.set cout,0xC0000020 ; the monitor's console output
.set dskio,0xC0000028 ; the monitor's disk I/O
 
; load the boot manager and start it
start:
add $29,$0,stacktop ; setup stack
add $4,$0,strtmsg ; say what is going on
jal msgout
add $4,$0,2 ; start loading with sector 2
add $5,$0,loadaddr ; where to load the boot manager
and $5,$5,0x3FFFFFFF ; convert to physical address
add $6,$0,30 ; 30 sectors to load
jal rdsct
add $8,$0,loadaddr ; start executing the boot manager
jr $8
 
; read disk sectors
; $4 start sector number (disk or partition relative)
; $5 transfer address
; $6 number of sectors
rdsct:
sub $29,$29,32
stw $31,$29,20
stw $6,$29,16 ; sector count
add $7,$5,$0 ; transfer address
add $6,$4,$17 ; relative sector -> absolute
add $5,$0,'r' ; command
add $4,$0,$16 ; disk number
add $8,$0,dskio
jalr $8
bne $2,$0,rderr ; error?
ldw $31,$29,20
add $29,$29,32
jr $31
 
; disk read error
rderr:
add $4,$0,dremsg
jal msgout
j halt
 
; output message
; $4 pointer to string
msgout:
sub $29,$29,8
stw $31,$29,4
stw $16,$29,0
add $16,$4,0 ; $16: pointer to string
msgout1:
ldbu $4,$16,0 ; get character
beq $4,$0,msgout2 ; done?
jal chrout ; output character
add $16,$16,1 ; bump pointer
j msgout1 ; continue
msgout2:
ldw $16,$29,0
ldw $31,$29,4
add $29,$29,8
jr $31
 
; output character
; $4 character
chrout:
sub $29,$29,4
stw $31,$29,0
add $8,$0,cout
jalr $8
ldw $31,$29,0
add $29,$29,4
jr $31
 
; halt execution by looping
halt:
add $4,$0,hltmsg
jal msgout
halt1:
j halt1
 
; messages
strtmsg:
.byte "MBR executing...", 0x0D, 0x0A, 0
dremsg:
.byte "disk read error", 0x0D, 0x0A, 0
hltmsg:
.byte "bootstrap halted", 0x0D, 0x0A, 0
 
; boot record signature
.locate 512-2
.byte 0x55, 0xAA
/stage1/Makefile
0,0 → 1,16
#
# Makefile to build the master boot record
#
 
BUILD = ../../../../build
 
all: mbr.bin
 
mbr.bin: mbr.o
$(BUILD)/bin/ld -h -rc 0xC0010000 -o mbr.bin mbr.o
 
mbr.o: mbr.s
$(BUILD)/bin/as -o mbr.o mbr.s
 
clean:
rm -f *~ mbr.o mbr.bin
/Makefile
0,0 → 1,28
#
# Makefile to build the master boot block (with an empty partition table)
#
 
BUILD = ../../../build
 
.PHONY: all install clean
 
all: mbootblk
 
install: mbootblk
mkdir -p $(BUILD)/run
cp mbootblk $(BUILD)/run
 
mbootblk: stage1/mbr.bin stage2/mboot.bin
dd if=/dev/zero of=./zeroes bs=512 count=1
cat stage1/mbr.bin zeroes stage2/mboot.bin >mbootblk
 
stage1/mbr.bin:
$(MAKE) -C stage1
 
stage2/mboot.bin:
$(MAKE) -C stage2
 
clean:
$(MAKE) -C stage1 clean
$(MAKE) -C stage2 clean
rm -f *~ zeroes mbootblk

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.