From ad17a401d69c7971ac83e449d6dc7d3fbeb6acc8 Mon Sep 17 00:00:00 2001 From: phcoder Date: Sun, 18 Oct 2009 14:10:31 +0200 Subject: [PATCH] new image format for mips. Asm part --- conf/mips.rmk | 5 +- configure.ac | 2 + genmk.rb | 2 +- include/grub/mips/kernel.h | 12 +++-- kern/mips/startup.S | 98 +++++++++++++++++++++++++++++++------- 5 files changed, 94 insertions(+), 25 deletions(-) diff --git a/conf/mips.rmk b/conf/mips.rmk index 9920f6878..a76ecac14 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -26,7 +26,7 @@ kernel_syms.lst: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h genke /bin/sh genkernsyms.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) # Programs -pkglib_PROGRAMS = kernel.img +pkglib_IMAGES = kernel.img # Utilities. sbin_UTILITIES = grub-mkdevicemap @@ -84,7 +84,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \ grub_emu_LDFLAGS = $(LIBCURSES) -kernel_img_SOURCES = kern/$(target_cpu)/$(target_machine)/startup.S \ +kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/$(target_machine)/init.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/reader.c kern/term.c \ @@ -97,6 +97,7 @@ kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = $(COMMON_LDFLAGS) -static-libgcc -lgcc \ -Wl,-N,-S,-Ttext,$(LINK_BASE),-Bstatic +kernel_img_FORMAT = binary # Scripts. sbin_SCRIPTS = diff --git a/configure.ac b/configure.ac index c02b8c0c9..f13cac52a 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,7 @@ if test "x$with_platform" = x; then powerpc-*) platform=ieee1275 ;; powerpc64-*) platform=ieee1275 ;; sparc64-*) platform=ieee1275 ;; + mips-*) platform=yeeloong ;; *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;; esac else @@ -92,6 +93,7 @@ case "$target_cpu"-"$platform" in sparc64-ieee1275) ;; mips-qemu-r4k) ;; mips-qemu-mipssim) ;; + mips-yeeloong) ;; *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; esac diff --git a/genmk.rb b/genmk.rb index 71b57816f..c608707b7 100644 --- a/genmk.rb +++ b/genmk.rb @@ -68,7 +68,7 @@ MOSTLYCLEAN_IMAGE_TARGETS += mostlyclean-image-#{@name}.#{@rule_count} ifneq ($(TARGET_APPLE_CC),1) #{@name}: #{exe} - $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@ + $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn $< $@ else ifneq (#{exe},kernel.exec) #{@name}: #{exe} ./grub-macho2img diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h index 326f1244d..3b578ef05 100644 --- a/include/grub/mips/kernel.h +++ b/include/grub/mips/kernel.h @@ -20,13 +20,15 @@ #define GRUB_KERNEL_CPU_HEADER 1 #define GRUB_MOD_ALIGN 0x1000 +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_MOD_GAP 0x0 -/* Minimal gap between _end and the start of the modules. It's a hack - for PowerMac to prevent "CLAIM failed" error. The real fix is to - rewrite grub-mkimage to generate valid ELF files. */ -#define GRUB_MOD_GAP 0x8000 +#define GRUB_KERNEL_CPU_RAW_SIZE 0x100 +#define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc +#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 -#define GRUB_KERNEL_CPU_PREFIX 0x8 +#define GRUB_KERNEL_CPU_PREFIX 0x0 #define GRUB_KERNEL_CPU_DATA_END 0x48 #endif diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 19de4779d..545aae32a 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -21,6 +21,8 @@ #include #include +#define BASE_ADDR 8 + .extern __bss_start .extern _end @@ -28,8 +30,84 @@ __start: _start: start: - b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX + bal codestart + . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE +compressed_size: + .long 0 + . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE +total_module_size: + .long 0 + . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE +kernel_image_size: + .long 0 +codestart: + /* Decompress the payload. */ + addiu $t2, $ra, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + lui $t1, %hi(compressed) + addiu $t1, %lo(compressed) + lw $t3, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($ra) + + /* $t2 contains source compressed address, $t1 is destination, + $t3 is compressed size. FIXME: put LZMA here. Don't clober $ra + */ +reloccont: + lb $t4, 0($t2) + sb $t4, 0($t1) + addiu $t1,$t1,1 + addiu $t2,$t2,1 + addiu $t3, 0xffff + bne $t3, $0, reloccont + + /* Move the modules out of BSS. */ + lui $t1, %hi(compressed) + addiu $t1, %lo(compressed) + lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($ra) + addu $t2, $t1, $t2 + + lui $t1, %hi(_end) + addiu $t1, %lo(_end) + addiu $t1, (GRUB_MOD_ALIGN-1) + li $t3, (GRUB_MOD_ALIGN-1) + nor $t3, $t3, $0 + and $t1, $t1, $t3 + /* Pass modules address as first argument. */ + move $a0, $t1 + + lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($ra) + + /* $t2 is source. $t1 is destination. $t3 is size. */ +modulesmovcont: + lb $t4, 0($t2) + sb $t4, 0($t1) + addiu $t1,$t1,1 + addiu $t2,$t2,1 + addiu $t3, 0xffff + bne $t3, $0, modulesmovcont + + /* Clean BSS. */ + + lui $t1, %hi(__bss_start) + addiu $t1, %lo(__bss_start) + lui $t2, %hi(_end) + addiu $t2, %lo(_end) +bsscont: + sb $0,0($t1) + addiu $t1,$t1,1 + sltu $t3,$t1,$t2 + bne $t3, $0, bsscont + + li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH + lui $t1, %hi(grub_main) + addiu $t1, %lo(grub_main) + +#if __mips >= 2 + sync +#endif + jr $t1 + + . = _start + GRUB_KERNEL_CPU_RAW_SIZE +compressed: + . = _start + GRUB_KERNEL_CPU_RAW_SIZE + GRUB_KERNEL_CPU_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -38,18 +116,4 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END -codestart: - lui $t1, %hi(__bss_start) - addiu $t1, %lo(__bss_start) - lui $t2, %hi(_end) - addiu $t2, %lo(_end) - -bsscont: - sb $0,0($t1) - addiu $t1,$t1,1 - sltu $t3,$t1,$t2 - bne $3, $0, bsscont - - li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH - b grub_main \ No newline at end of file + . = _start + GRUB_KERNEL_CPU_RAW_SIZE + GRUB_KERNEL_CPU_DATA_END