]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
asm part for mips decompressor
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 21 Sep 2010 08:14:08 +0000 (10:14 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 21 Sep 2010 08:14:08 +0000 (10:14 +0200)
grub-core/Makefile.core.def
grub-core/boot/mips/startup_raw.S [new file with mode: 0644]
grub-core/kern/mips/cache.S
grub-core/kern/mips/cache_flush.S
grub-core/kern/mips/startup.S
grub-core/lib/mips/relocator_asm.S
include/grub/offsets.h
util/grub-mkimage.c

index 2fca91430fbe6c200f423cfb443d302977a2c3aa..3341cb6789e85488459472be342e18b651ffd495 100644 (file)
@@ -275,6 +275,19 @@ image = {
   enable = i386_pc;
 };
 
+image = {
+  name = decompress;
+  mips = boot/mips/startup_raw.S;
+  common = lib/LzmaDec.c;
+
+  mips_cppflags = '-DGRUB_MACHINE_LINK_ADDR=0x80200000';
+
+  objcopyflags = '-O binary';
+  ldflags = '-lgcc -static-libgcc -Wl,-Ttext,0x80100000';
+  cflags = '-static-libgcc';
+  enable = mips;
+};
+
 image = {
   name = fwstart;
   mips_yeeloong = boot/mips/yeeloong/fwstart.S;
diff --git a/grub-core/boot/mips/startup_raw.S b/grub-core/boot/mips/startup_raw.S
new file mode 100644 (file)
index 0000000..67dc2ec
--- /dev/null
@@ -0,0 +1,186 @@
+/* startup.S - Startup code for the MIPS.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/symbol.h>
+#include <grub/offsets.h>
+#include <grub/machine/memory.h>
+#include <grub/offsets.h>
+
+#define BASE_ADDR 8
+
+.extern __bss_start
+.extern _end
+
+       .globl __start, _start, start
+       .set noreorder
+       .set nomacro
+__start:
+_start:
+start:         
+
+       bal codestart
+        nop
+base:  
+       . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
+compressed_size:
+       .long 0
+       . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE
+uncompressed_size:
+       .long 0
+codestart:
+       /* Save our base.  */
+       move $s0, $ra
+
+       /* Parse arguments. Has to be done before relocation.
+       So need to do it in asm.  */
+#if 0 // def GRUB_MACHINE_MIPS_YEELOONG
+       move $s2, $zero
+       move $s3, $zero
+       move $s4, $zero
+       move $s5, $zero
+
+       /* $a2 has the environment.  */
+       addiu $t0, $a2, 1
+       beq $t0, $zero, argdone
+        nop
+       move $t0, $a2   
+argcont:       
+       lw $t1, 0($t0)
+       beq $t1, $zero, argdone
+        nop
+#define DO_PARSE(str, reg) \
+       addiu $t2, $s0, (str-base);\
+       bal parsestr;\
+       beq $v0, $zero, 1f;\
+        nop              ;\
+       b 2f;\
+        move reg, $v0;  
+1:     
+       DO_PARSE (busclockstr, $s2)
+       DO_PARSE (cpuclockstr, $s3)
+       DO_PARSE (memsizestr, $s4)
+       DO_PARSE (highmemsizestr, $s5)
+2:     
+       b argcont
+        addiu $t0, $t0, 4       
+parsestr:
+       move $v0, $zero
+       move $t3, $t1
+3:     
+       lb $t4, 0($t2)
+       lb $t5, 0($t3)
+       addiu $t2, $t2, 1
+       addiu $t3, $t3, 1
+       beq $t5, $zero, 1f
+        nop
+       beq $t5, $t4, 3b
+        nop
+       bne $t4, $zero, 1f
+        nop
+
+       addiu $t3, $t3, 0xffff
+digcont:       
+       lb $t5, 0($t3)
+       /* Substract '0' from digit.  */
+       addiu $t5, $t5, 0xffd0
+       bltz $t5, 1f
+        nop
+       addiu $t4, $t5, 0xfff7
+       bgtz $t4, 1f
+        nop
+       /* Multiply $v0 by 10 with bitshifts. */
+       sll $v0, $v0, 1
+       sll $t4, $v0, 2
+       addu $v0, $v0, $t4
+       addu $v0, $v0, $t5
+       addiu $t3, $t3, 1
+       b digcont
+        nop
+1:
+       jr $ra
+        nop
+busclockstr:   .asciiz "busclock="
+cpuclockstr:   .asciiz "cpuclock="
+memsizestr:    .asciiz "memsize="
+highmemsizestr:        .asciiz "highmemsize="
+       .p2align 2
+argdone:
+#endif
+       /* Copy the decompressor. */
+       lui $t1, %hi(base)
+       addiu $t1, $t1, %lo(base)
+       lui $t3, %hi(__bss_start)
+       addiu $t3, $t3, %lo(__bss_start)
+       move $t2, $s0
+
+1:
+       beq $t1, $t3, 2f
+        lb $t4, 0($t2)
+       sb $t4, 0($t1)
+       addiu $t1, $t1, 1
+       b 1b
+        addiu $t2, $t2, 1
+2:
+       /* Clean out its BSS.  */
+       lui $t1, %hi(__bss_start)
+       addiu $t1, $t1, %lo(__bss_start)
+       lui $t2, %hi(_end)
+       addiu $t2, $t2, %lo(_end)
+1:
+       beq $t1, $t2, 2f
+        nop
+       sb $zero, 0($t1)
+       b 1b
+        addiu $t1, $t1, 1
+2:
+
+       /* Decompress the payload. */
+       lui $a0, %hi(__bss_start)
+       addiu $a0, $a0, %lo(__bss_start)
+       lui $t0, %hi(base)
+       addiu $t0, $t0, %lo(base)
+       subu $a0, $a0, $t0
+       addu $a0, $a0, $s0
+
+       lui $a1, %hi(GRUB_MACHINE_LINK_ADDR)
+       addiu $a1, %lo(GRUB_MACHINE_LINK_ADDR)
+       lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
+       lw $a3, (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
+       move $s1, $a1
+
+       /* $a0 contains source compressed address, $a1 is destination,
+          $a2 is compressed size, $a3 is uncompressed size. 
+       */
+       move $s6, $a3
+
+       lui $sp, %hi(_start)
+
+       bal EXT_C(grub_decompress_core)
+        addiu $sp, $sp, %lo(_start)
+       
+       move $a0, $s1
+       move $a1, $s6
+
+#include "../../kern/mips/cache_flush.S"
+
+       lui $t1, %hi(GRUB_MACHINE_LINK_ADDR)
+       addiu $t1, %lo(GRUB_MACHINE_LINK_ADDR)
+
+       jr $t1
+        nop
index 2c35b6da2a731b355c71f0b0f87e7c8a2ed46ad9..02dc3355ff027f2e52a478db7742cc9edaa6d024 100644 (file)
@@ -1,6 +1,9 @@
 
 #include <grub/symbol.h>
 
+       .set nomacro
+       .set noreorder
+
 FUNCTION (grub_cpu_flush_cache)
 FUNCTION (grub_arch_sync_caches)
 #include "cache_flush.S"
index 5667ee7b4f66a7a96cb9f9b774a32bdd6b9736a5..11096c0353d0f21272478b7d5190747d1ce9b147 100644 (file)
@@ -9,15 +9,15 @@
        subu $t1, $t3, $t2
 1:
        cache 1, 0($t0)
-       addiu $t0, $t0, 0x1
        addiu $t1, $t1, 0xffff
        bne $t1, $zero, 1b
+        addiu $t0, $t0, 0x1
        sync
        move $t0, $t2
        subu $t1, $t3, $t2
 2:
        cache 0, 0($t0)
-       addiu $t0, $t0, 0x1
        addiu $t1, $t1, 0xffff
        bne $t1, $zero, 2b
+        addiu $t0, $t0, 0x1
        sync
index 6811353ead95f55ce9b7b2bec37a030e08ce1b16..1b27a5b1fc45cfbd1889cf7f8f041372ab6f5183 100644 (file)
 #include <grub/machine/memory.h>
 #include <grub/offsets.h>
 
-#define BASE_ADDR 8
-       
-.extern __bss_start
-.extern _end
-       
+#define BASE_ADDR 8    
+
        .globl __start, _start, start
+       .set noreorder
+       .set nomacro
 __start:
 _start:
-start: 
-       bal codestart
-base:  
-       . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
-compressed_size:
-       .long 0
-       . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
-total_module_size:
-       .long 0
-       . = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE
-kernel_image_size:     
-       .long   0
-codestart:
-       /* Save our base.  */
-       move $s0, $ra
-
-       /* Parse arguments. Has to be done before relocation.
-       So need to do it in asm.  */
-#ifdef GRUB_MACHINE_MIPS_YEELOONG
-       move $s2, $zero
-       move $s3, $zero
-       move $s4, $zero
-       move $s5, $zero
-
-       /* $a2 has the environment.  */
-       addiu $t0, $a2, 1
-       beq $t0, $zero, argdone
-       move $t0, $a2   
-argcont:       
-       lw $t1, 0($t0)
-       beq $t1, $zero, argdone
-#define DO_PARSE(str, reg) \
-       addiu $t2, $s0, (str-base);\
-       bal parsestr;\
-       beq $v0, $zero, 1f;\
-       move reg, $v0;\
-       b 2f;\
-1:     
-       DO_PARSE (busclockstr, $s2)
-       DO_PARSE (cpuclockstr, $s3)
-       DO_PARSE (memsizestr, $s4)
-       DO_PARSE (highmemsizestr, $s5)
-2:     
-       addiu $t0, $t0, 4
-       b argcont
-parsestr:
-       move $v0, $zero
-       move $t3, $t1
-3:     
-       lb $t4, 0($t2)
-       lb $t5, 0($t3)
-       addiu $t2, $t2, 1
-       addiu $t3, $t3, 1
-       beq $t5, $zero, 1f
-       beq $t5, $t4, 3b
-       bne $t4, $zero, 1f
-
-       addiu $t3, $t3, 0xffff
-digcont:       
-       lb $t5, 0($t3)
-       /* Substract '0' from digit.  */
-       addiu $t5, $t5, 0xffd0
-       bltz $t5, 1f
-       addiu $t4, $t5, 0xfff7
-       bgtz $t4, 1f
-       /* Multiply $v0 by 10 with bitshifts. */
-       sll $v0, $v0, 1
-       sll $t4, $v0, 2
-       addu $v0, $v0, $t4
-       addu $v0, $v0, $t5
-       addiu $t3, $t3, 1
-       b digcont
-1:
-       jr $ra
-busclockstr:   .asciiz "busclock="
-cpuclockstr:   .asciiz "cpuclock="
-memsizestr:    .asciiz "memsize="
-highmemsizestr:        .asciiz "highmemsize="
-       .p2align 2
-argdone:
-#endif
-
-       /* Decompress the payload. */
-       addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR
-       lui $a1, %hi(compressed)
-       addiu $a1, %lo(compressed)
-       lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
-       move $s1, $a1
-
-       /* $a0 contains source compressed address, $a1 is destination,
-          $a2 is compressed size. FIXME: put LZMA here. Don't clober $s0,
-          $s1, $s2, $s3, $s4 and $s5.
-          On return $v0 contains uncompressed size.
-       */
-       move $v0, $a2
-reloccont:
-       lb $t4, 0($a0)
-       sb $t4, 0($a1)
-       addiu $a1,$a1,1
-       addiu $a0,$a0,1
-       addiu $a2, 0xffff
-       bne $a2, $0, reloccont
-
-       move $a0, $s1
-       move $a1, $v0
-
-#include "cache_flush.S"
-
-       lui $t1, %hi(cont)
-       addiu $t1, %lo(cont)
+start:         
+.extern __bss_start
+.extern _end
+       bal cont
+        nop
 
-       jr $t1
-       . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
-compressed:    
        . = _start + GRUB_KERNEL_MACHINE_PREFIX
 
 VARIABLE(grub_prefix)
@@ -166,6 +57,8 @@ VARIABLE (grub_arch_highmemsize)
        .long 0
 #endif
 cont:
+       /* Save our base.  */
+       move $s0, $ra
 
 #ifdef GRUB_MACHINE_MIPS_YEELOONG
        lui $t1, %hi(grub_arch_busclock)
@@ -177,10 +70,8 @@ cont:
 #endif
 
        /* Move the modules out of BSS.  */
-       lui $t1, %hi(_start)
-       addiu $t1, %lo(_start)
-       lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0)
-       addu $t2, $t1, $t2
+       lui $t2, %hi(_end)
+       addiu $t2, %lo(_end)
        
        lui $t1, %hi(_end)
        addiu $t1, %lo(_end)
@@ -201,11 +92,11 @@ cont:
 modulesmovcont:
        lb $t4, 0($t2)
        sb $t4, 0($t1)
-       addiu $t1,$t1,0xffff
-       addiu $t2,$t2,0xffff
-       addiu $t3, 0xffff
+       addiu $t1, $t1, -1
+       addiu $t3, $t3, -1
        bne $t3, $0, modulesmovcont
-
+        addiu $t2, $t2, -1
+       
        /* Clean BSS.  */
        
        lui $t1, %hi(__bss_start)
@@ -214,13 +105,14 @@ modulesmovcont:
        addiu $t2, %lo(_end)
 bsscont:
        sb $0,0($t1)
-       addiu $t1,$t1,1
-       sltu $t3,$t1,$t2
+       sltu $t3, $t1, $t2
        bne $t3, $0, bsscont
+        addiu $t1, $t1, 1
 
        li $sp, GRUB_MACHINE_MEMORY_STACK_HIGH
        lui $t1, %hi(grub_main)
        addiu $t1, %lo(grub_main)
 
        jr $t1
+        nop
 
index 3408b59e100e90a10255eb6d192a38a0069f8a70..1d142a4f355b4961edb22b324b05bb941ba88137 100644 (file)
@@ -20,6 +20,9 @@
        
        .p2align        4       /* force 16-byte alignment */
 
+       .set noreorder
+       .set nomacro
+
 VARIABLE (grub_relocator_forward_start)
        move $a0, $9
        move $a1, $10
@@ -28,9 +31,9 @@ copycont1:
        lb $11,0($8)
        sb $11,0($9)
        addiu $8, $8, 1
-       addiu $9, $9, 1
        addiu $10, $10, -1
        bne $10, $0, copycont1
+        addiu $9, $9, 1
 
 #include "../../kern/mips/cache_flush.S"
 
@@ -49,9 +52,9 @@ copycont2:
        lb $11,0($8)
        sb $11,0($9)
        addiu $8, $8, -1
-       addiu $9, $9, -1
        addiu $10, $10, -1
        bne $10, $0, copycont2
+        addiu $9, $9, -1
 
 #include "../../kern/mips/cache_flush.S"
 
index 47eb6c9bdbb081f0c113fb79c55cfc6c09aae784..8caa27c2f35b10d841d6303b01b3d2e9fd234ace 100644 (file)
 
 #define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN  32
 
-#define GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE        0x200
-#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE        0x8
-#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE      0xc
-#define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE      0x10
+#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE          0x8
+#define GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE        0xc
 
-#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX               GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE
-#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END   GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48
+#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE    0x08
+#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX               0x0c
+#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END           0x54
 
 /* The offset of GRUB_PREFIX.  */
 #define GRUB_KERNEL_I386_EFI_PREFIX            0x8
 #define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE)
 #define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE)
 #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE)
+#define GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _UNCOMPRESSED_SIZE)
 
 #define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX)
 #define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX_END)
index d798ad052f9dd4186cee034ace94b59e795b58a5..ee007a54b2637f98876ec95a9f567227bfbf96ac 100644 (file)
@@ -248,13 +248,13 @@ struct image_target_desc image_targets[] =
       .voidp_sizeof = 4,
       .bigendian = 0,
       .id = IMAGE_YEELOONG_FLASH, 
-      .flags = PLATFORM_FLAGS_NONE,
+      .flags = PLATFORM_FLAGS_LZMA,
       .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX,
       .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END,
-      .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE,
+      .raw_size = 0,
       .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE,
-      .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE,
-      .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE,
+      .compressed_size = TARGET_NO_FIELD,
+      .kernel_image_size = TARGET_NO_FIELD,
       .section_align = 1,
       .vaddr_offset = 0,
       .install_dos_part = TARGET_NO_FIELD,
@@ -268,13 +268,13 @@ struct image_target_desc image_targets[] =
       .voidp_sizeof = 4,
       .bigendian = 0,
       .id = IMAGE_YEELOONG_ELF, 
-      .flags = PLATFORM_FLAGS_NONE,
+      .flags = PLATFORM_FLAGS_LZMA,
       .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX,
       .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END,
-      .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE,
+      .raw_size = 0,
       .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE,
-      .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE,
-      .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE,
+      .compressed_size = TARGET_NO_FIELD,
+      .kernel_image_size = TARGET_NO_FIELD,
       .section_align = 1,
       .vaddr_offset = 0,
       .install_dos_part = TARGET_NO_FIELD,
@@ -680,6 +680,41 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
        = grub_host_to_target32 (-2);
     }
 
+  if (image_target->id == IMAGE_YEELOONG_FLASH
+      || image_target->id == IMAGE_YEELOONG_ELF)
+    {
+      char *full_img;
+      size_t full_size;
+      char *decompress_path, *decompress_img;
+      size_t decompress_size;
+      
+      decompress_path = grub_util_get_path (dir, "decompress.img");
+      decompress_size = grub_util_get_image_size (decompress_path);
+      decompress_img = grub_util_read_image (decompress_path);
+
+      *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE))
+       = grub_host_to_target32 (core_size);
+
+      *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE))
+       = grub_host_to_target32 (kernel_size + total_module_size);
+
+      full_size = core_size + decompress_size;
+
+      full_img = xmalloc (full_size);
+      memset (full_img, 0, full_size); 
+
+      memcpy (full_img, decompress_img, decompress_size);
+
+      memcpy (full_img + decompress_size, core_img, core_size);
+
+      memset (full_img + decompress_size + core_size, 0,
+             full_size - (decompress_size + core_size));
+
+      free (core_img);
+      core_img = full_img;
+      core_size = full_size;
+    }
+
   switch (image_target->id)
     {
     case IMAGE_I386_PC: