Fixed build system, added basic support for kernel command line. Added

memory size argument passing to second-stage loader.
master
Philippe Vachon 16 years ago
parent 3ed164c536
commit 28cfe632fd

@ -35,10 +35,12 @@ AR=$(CROSS_COMPILE)ar
LD=$(CROSS_COMPILE)ld
OBJCOPY=$(CROSS_COMPILE)objcopy
MACHDIR=mach/$(TARGET)
# command to prepare a binary
RAW=${OBJCOPY} --strip-unneeded --alt-machine-code ${MACHCODE}
INCLUDE=-Iinclude/ -Imach/${TARGET}
INCLUDE=-Iinclude/ -Imach/${TARGET} -Iinclude/mach/${TARGET}
CFLAGS=$(INCLUDE) -fno-builtin -fomit-frame-pointer -fno-pic -mno-abicalls \
-Wall
@ -48,12 +50,18 @@ ASFLAGS=-xassembler-with-cpp -traditional-cpp
LDFLAGS=--omagic -nostartfiles -nostdlib --discard-all --strip-all \
-Ttext ${TEXTADDR} --entry _start
OBJECTS=start.o main.o printf.o promlib.o elf_loader.o
OBJECTS=main.o printf.o elf_loader.o
LINKOBJ=${OBJECTS} $(MACHDIR)/promlib.o $(MACHDIR)/start.o #$(MACHDIR)/platform.o
THISFLAGS='LDFLAGS=$(LDFLAGS)' 'ASFLAGS=$(ASFLAGS)' \
'CROSS_COMPILE=$(CROSS_COMPILE)' 'CFLAGS=$(CFLAGS)' 'CC=$(CC)'
all: ${OBJECTS} ${PROG}
${PROG}: ${OBJECTS}
${CC} ${LDFLAGS} ${OBJECTS} -o ${PROG}.elf
${PROG}: sub ${OBJECTS}
${CC} ${LDFLAGS} ${LINKOBJ} -o ${PROG}.elf
${RAW} ${PROG}.elf ${PROG}.bin
.c.o:
@ -62,7 +70,19 @@ ${PROG}: ${OBJECTS}
.S.o:
${CC} ${CFLAGS} ${ASFLAGS} -c $<
clean:
-rm *.o
-rm ${PROG}.elf
-rm ${PROG}.bin
sub:
@for i in $(MACHDIR); do \
echo "Making all in $$i..."; \
(cd $$i; $(MAKE) $(MFLAGS) $(THISFLAGS) all); done
(cd second/; $(MAKE) $(MFLAGS))
subclean:
@for i in $(MACHDIR); do \
echo "Cleaning all in $$i..."; \
(cd $$i; $(MAKE) $(MFLAGS) clean); done
(cd second/; $(MAKE) $(MFLAGS) clean)
clean: subclean
-rm -f *.o
-rm -f ${PROG}.elf
-rm -f ${PROG}.bin

@ -37,6 +37,8 @@ When the router boots, it will load CILO; CILO then will prompt you to
select the file you want to boot. Enter the file name you wish to boot, and
away you go!
Of course, it makes sense to put your kernel on your flash device as well.
5. What hardware is supported?
At this time, the Cisco 3600 Series of routers (3620 and 3640 at least) are
very well supported. As well, preliminary support is underway for the

@ -2,6 +2,9 @@
#include <promlib.h>
#include <printf.h>
/* platform-specific defines */
#include <platform.h>
void read(void *ptr, uint32_t size, uint32_t count, uint32_t base,
uint32_t offset);
@ -19,12 +22,8 @@ void load_elf32_section(uint32_t base, uint32_t address,
{
uint8_t *elf_loc = (uint8_t *)address;
printf("read(%08x, %08x, 1, %08x, %08x);\n",
address, length, base, file_offset);
read(elf_loc, length, 1, base, file_offset);
printf("Read %d bytes into memory at location %#8x.\n", length, address);
}
/**
@ -40,8 +39,6 @@ void load_elf32_uninitialized_memory(uint32_t address, uint32_t length)
for (i = 0; i < length; i++) {
p[i] = 0;
}
printf("Created uninitialized data section of %d bytes at %#8x.\n", i,
address);
}
/**
@ -147,11 +144,11 @@ int load_elf32_file(uint32_t base, uint32_t loader_addr)
if (phdr.type != ELF_PT_LOAD) continue;
uint32_t leftover = phdr.memsz - phdr.filesz;
load_elf32_section(base, mem_sz + hdr.entry + phdr.paddr,
load_elf32_section(base, mem_sz + phdr.paddr,
phdr.offset, phdr.filesz);
if (leftover > 0) {
load_elf32_uninitialized_memory(mem_sz + hdr.entry + phdr.paddr +
load_elf32_uninitialized_memory(mem_sz + phdr.paddr +
phdr.filesz, leftover);
}
}
@ -161,66 +158,13 @@ int load_elf32_file(uint32_t base, uint32_t loader_addr)
printf("Loaded %d bytes at %08x.\n", mem_sz, load_offset);
/* struct elf32_section_header shdr; */
/* read in section headers, load sections */
#if 0
uint32_t sh_offset = hdr.shoff;
for (i = 0; i < hdr.shnum; i++) {
printf("reading: base: %08x, sh_offset: %08x\n", base, sh_offset);
read(&shdr, sizeof(struct elf32_section_header), 1, base, sh_offset);
printf("\n\nJust read section header %d\n", i);
printf("\tName: %u\n", shdr.name);
printf("\tType: %#8x: %s\n", shdr.type, sh_type_to_string(shdr.type));
printf("\tFlags: %#8x\n", shdr.flags);
printf("\t\t%c%c%c\n", ELF_SHF_ALLOCD(shdr.flags) ? 'A' : '-',
ELF_SHF_WRITABLE(shdr.flags) ? 'w' : '-',
ELF_SHF_EXECUTABLE(shdr.flags) ? 'x' : '-');
printf("\tAddress: %#8x\n", shdr.addr);
printf("\tOffset: %u bytes\n", shdr.offset);
printf("\tSize: %u bytes\n", shdr.size);
printf("\tLink: %#8x\n", shdr.link);
printf("\tAdditional Info: %#8x\n", shdr.info);
printf("\tAddress Alignment: %#8x\n", shdr.addralign);
printf("\tPer-Entry Size: %u bytes\n\n", shdr.entsize);
if (!ELF_SHF_ALLOCD(shdr.flags)) {
sh_offset += sizeof(struct elf32_section_header);
continue;
}
printf("Param: base: %08x addr: %08x offset: %08x size: %08x\n",
base, shdr.addr, shdr.offset, shdr.size);
/* load section */
switch (shdr.type) {
case ELF_SHT_NULL: /* no data to be loaded */
break;
case ELF_SHT_NOBITS:
/* zero out this data */
load_elf32_uninitialized_memory(shdr.addr + mem_sz,
shdr.size);
break;
case ELF_SHT_PROGBITS:
/* program bits and such */
load_elf32_section(base, shdr.addr + mem_sz, shdr.offset,
shdr.size);
break;
default:
printf("WARNING: Section type %08x cannot be loaded by "
"CiscoLoad.\n", shdr.type);
}
sh_offset += sizeof(struct elf32_section_header);
}
#endif
printf("Kicking into Linux.\n");
#ifdef DEBUG
printf("bootcpy: %08x, kdataoffset: %08x, kdatalength: %08x\n",
loader_addr, load_offset, mem_sz);
printf("kentrypt: %08x, kloadoffset: %08x\n", hdr.entry, hdr.entry);
#endif
/* Jump to the copy routine */
asm (".set noreorder\n"

@ -12,5 +12,5 @@ elftool: $(OBJECTS)
gcc $(CFLAGS) -c $<
clean:
rm *.o
rm $(PROG)
-rm -f *.o
-rm -f $(PROG)

@ -0,0 +1,8 @@
#ifndef _INCLUDE_MACH_C3600_PLATFORM_H
#define _INCLUDE_MACH_C3600_PLATFORM_H
#define FLASH_BASE 0x30000000
#define KERNEL_ENTRY_POINT 0x80008000
#define MEMORY_BASE 0x80000000
#endif /* _INCLUDE_MACH_C3600_PLATFORM_H */

@ -88,4 +88,20 @@ inline int memcpy(void *dst, const void *src, int n)
return i;
}
/**
* strchr
*/
inline const char *strchr(const char *s, int c)
{
const char *ptr = s;
while (*ptr != '\0') {
if (*(ptr++) == (char)c) {
return ptr;
}
}
return NULL;
}
#endif /* _STRING_H */

@ -0,0 +1,2 @@
The mach/ directory contains platform-specific defines for CiscoLoad.

@ -0,0 +1,18 @@
ifndef CROSS_COMPILE
CROSS_COMPILE=mips-elf-
endif
OBJECTS=start.o promlib.o
INCLUDE=-I../../include
all: ${OBJECTS}
.c.o:
$(CC) ${CFLAGS} ${INCLUDE} -c $<
.S.o:
$(CC) ${CFLAGS} ${INCLUDE} ${ASFLAGS} -c $<
clean:
-rm -f *.o

@ -2,18 +2,15 @@
* (c) 2008 Philippe Vachon <philippe@cowpig.ca>
* Licensed under the GNU General Public License v2
*/
#include <promlib.h>
#include <printf.h>
#include <addr.h>
#include <elf.h>
#include <elf_loader.h>
#include <string.h>
#include <promlib.h>
/**
* Todo: Add these to platform-specific header
*/
#define FLASH_BASE 0x30000000
#define KERNEL_ENTRY_POINT 0x80008000
/* platform-specific defines */
#include <platform.h>
#define FS_FILE_MAGIC 0xbad00b1e
@ -133,7 +130,10 @@ void start_bootloader()
{
int r = 0;
int f;
char buf[48];
char buf[129];
char *cmd_line = (char *)MEMORY_BASE;
buf[128] = '\0';
/* determine amount of RAM present */
c_putc('I');
@ -164,8 +164,19 @@ void start_bootloader()
printf("Available files:\n");
flash_directory(FLASH_BASE);
enter_filename:
printf("\nEnter filename to boot:\n> ");
c_gets(buf, 48);
c_gets(buf, 128);
/* determine if a command line string has been appended to kernel name */
const char *cmd_line_append;
if ((cmd_line_append = strchr(buf, ' ')) != NULL) {
strcpy(cmd_line, cmd_line_append);
} else {
cmd_line[0] = '\0';
}
printf("\n\nAttempting to load file %s\n", buf);
uint32_t kernel_off = find_file(buf, FLASH_BASE);
@ -182,12 +193,14 @@ void start_bootloader()
} else {
printf("Booting \"%s\" from flash at 0x%08x\n", buf,
FLASH_BASE + kernel_off);
printf("DEBUG: cmd_line: %s\n", cmd_line);
if (load_elf32_file(FLASH_BASE + kernel_off, FLASH_BASE + loader_off)
< 0)
{
printf("Fatal error while loading kernel. Aborting.\n");
}
}
goto enter_filename;
/* return to ROMMON */
}

@ -27,6 +27,20 @@ LEAF(_start)
nop
/* put the stack pointer up at top of memory */
li a0, 4
syscall
nop
li sp, 0x80000000
add sp, sp, v0
move a0, v0
li a1, 0x80000000
li a3, 0
li v0, 0
jr a2 # jump to kernel entry point
nop

Loading…
Cancel
Save