├── README.md ├── device └── catalyst2900xl │ ├── README │ └── helloworld │ ├── build.sh │ └── helloworld.s ├── loader ├── CMakeLists.txt ├── README.md ├── build │ └── toolchain-powerpc.cmake └── src │ ├── CMakeLists.txt │ ├── arch │ ├── CMakeLists.txt │ ├── io.h │ ├── platform.h │ └── ppc403ga │ │ ├── io.c │ │ ├── platform.c │ │ └── start.S │ ├── klib │ ├── CMakeLists.txt │ ├── klib.h │ ├── memchr.c │ ├── printf.c │ └── strlen.c │ └── main.c └── mziptools ├── Makefile ├── README ├── crc16.c ├── crc16.h ├── elf2mzip.c ├── mzip.c ├── mzip.h └── readmzip.c /README.md: -------------------------------------------------------------------------------- 1 | # Definition 2 | ROMMON: Cisco bootloader 3 | IOS: Cisco operating system 4 | 5 | # Project tree 6 | [mziptools]: some tools to manipulate MZIP files which can then be used to boot 7 | our own code on the ROMMON bootloader. 8 | [loader]: a second stage bootloader 9 | [device]: helloworld (tm) for cisco devices 10 | -------------------------------------------------------------------------------- /device/catalyst2900xl/README: -------------------------------------------------------------------------------- 1 | Information on the Cisco Catalyst 2900XL 2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 | 4 | Architecture 5 | ~~~~~~~~~~~~ 6 | CPU: PowerPC 403GA 7 | 8 | Requirement 9 | ~~~~~~~~~~~ 10 | * You need a PowerPC toolchain 11 | -------------------------------------------------------------------------------- /device/catalyst2900xl/helloworld/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | powerpc-elf-as -m403 -Wall helloworld.s -o helloworld.o 4 | powerpc-elf-ld --omagic --strip-all --discard-all --entry=_start -Ttext=3000 -o helloworld.elf helloworld.o 5 | elf2mzip helloworld.elf helloworld.bin 6 | -------------------------------------------------------------------------------- /device/catalyst2900xl/helloworld/helloworld.s: -------------------------------------------------------------------------------- 1 | .data 2 | helloworld: 3 | .ascii "Hello Cisco!\r\n" 4 | 5 | .text 6 | .global _start 7 | 8 | # 9 | # MAIN 10 | # r3: boot_flags 11 | # r4: filename 12 | # 13 | _start: 14 | mflr %r0 15 | stw %r0, 8(%r1) 16 | 17 | lis %r10, 0x0 18 | li %r10, 0x0 19 | lis %r10, 0x4000 20 | 21 | lis %r3,helloworld@ha 22 | addi %r3,%r3,helloworld@l 23 | li %r4, 14 24 | bl send_string 25 | 26 | # ret 27 | # cannot ret to the bootloader 28 | 29 | # 30 | # SEND STRING 31 | # r3: string 32 | # r4: length 33 | # 34 | send_string: 35 | mflr %r0, 36 | stw %r0, 8(%r1) 37 | 38 | # init var 39 | mr %r6,%r3 # string 40 | mr %r7,%r4 # length 41 | li %r8,0 # counter 42 | 43 | # send loop 44 | loop: 45 | lbzx %r3, %r6, %r8 46 | bl send_char 47 | addi %r8,%r8,1 48 | cmp 0,%r8,%r7 49 | blt loop 50 | 51 | # ret 52 | end: 53 | lwz %r0, 8(%r1) 54 | mtlr %r0 55 | blr 56 | 57 | # 58 | # SEND CHAR 59 | # r3: character 60 | # 61 | send_char: 62 | mflr %r0 63 | stw %r0, 8(%r1) 64 | 65 | # wait for transmit buffer ready 66 | loop_transmit_buffer_ready: 67 | lbz %r11, 0(%r10) 68 | andi. %r11, %r11, 0x04 69 | beq 0,loop_transmit_buffer_ready 70 | 71 | # put char in transmission buffer 72 | transmit_char: 73 | stb %r3, 9(%r10) 74 | 75 | # ret 76 | ret: 77 | lwz %r0, 8(%r1) 78 | mtlr %r0 79 | blr 80 | -------------------------------------------------------------------------------- /loader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 2 | # Benjamin Vanheuverzwijn 3 | # 4 | # All or some portions of this file are derived from material licensed 5 | # to the University of California by American Telephone and Telegraph 6 | # Co. or Unix System Laboratories, Inc. and are reproduced herein with 7 | # the permission of UNIX System Laboratories, Inc. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions 11 | # are met: 12 | # 1. Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # 2. Redistributions in binary form must reproduce the above copyright 15 | # notice, this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # 3. The names of its contributors may not be used to endorse or promote 18 | # products derived from this software without specific prior written 19 | # permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | # SUCH DAMAGE. 32 | # 33 | 34 | cmake_minimum_required(VERSION 2.6) 35 | 36 | project(loader C ASM) 37 | 38 | set(SOURCE "") 39 | set(HEADERS "") 40 | 41 | add_definitions(-Wall -mtune=403 -Wa,-m403 -fno-builtin ) 42 | set(CMAKE_EXE_LINKER_FLAGS -Wl,--omagic,--strip-all,--discard-all,--entry=_start,-Ttext=3000) 43 | 44 | add_subdirectory(${PROJECT_SOURCE_DIR}/src) 45 | 46 | add_executable(loader ${SOURCE}) 47 | -------------------------------------------------------------------------------- /loader/README.md: -------------------------------------------------------------------------------- 1 | # What is it? 2 | This is an attemp to build an ELF loader to make it easier to run 3rd party 3 | software on your hardware. This is somewhat a second stage bootloader. 4 | 5 | # How to build? 6 | You will need a powerpc crosscompiler ready. 7 | Adjust the path to your powerpc crosscompiler in build/toolchain-powerpc.cmake 8 | and then: 9 | $ cd build 10 | $ cmake -DCMAKE_TOOLCHAIN_FILE=./toolchain-powerpc.cmake ../ 11 | 12 | # License? 13 | 3-clause BSD license 14 | -------------------------------------------------------------------------------- /loader/build/toolchain-powerpc.cmake: -------------------------------------------------------------------------------- 1 | SET(CMAKE_SYSTEM_NAME Generic) 2 | SET(CMAKE_SYSTEM_VERSION 1) 3 | SET(CMAKE_SYSTEM_PROCESSOR ppc403ga) 4 | 5 | SET(CMAKE_C_COMPILER /opt/toolchain/powerpc/bin/powerpc-elf-gcc) 6 | SET(CMAKE_CXX_COMPILER /opt/toolchain/powerpc/bin/powerpc-elf-gcc) 7 | 8 | SET(CMAKE_FIND_ROOT_PATH NEVER) 9 | SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 10 | 11 | SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 12 | SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 13 | 14 | -------------------------------------------------------------------------------- /loader/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 2 | # Benjamin Vanheuverzwijn 3 | # 4 | # All or some portions of this file are derived from material licensed 5 | # to the University of California by American Telephone and Telegraph 6 | # Co. or Unix System Laboratories, Inc. and are reproduced herein with 7 | # the permission of UNIX System Laboratories, Inc. 8 | # 9 | # Redistribution and use in source and binary forms, with or without 10 | # modification, are permitted provided that the following conditions 11 | # are met: 12 | # 1. Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # 2. Redistributions in binary form must reproduce the above copyright 15 | # notice, this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # 3. The names of its contributors may not be used to endorse or promote 18 | # products derived from this software without specific prior written 19 | # permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | # SUCH DAMAGE. 32 | # 33 | 34 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/klib) 35 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/arch) 36 | 37 | set(SOURCE 38 | ${SOURCE} 39 | ${CMAKE_CURRENT_SOURCE_DIR}/main.c 40 | PARENT_SCOPE) 41 | 42 | set(HEADERS 43 | ${HEADERS} 44 | PARENT_SCOPE) 45 | -------------------------------------------------------------------------------- /loader/src/arch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2013 3 | # Benjamin Vanheuverzwijn 4 | # 5 | # All or some portions of this file are derived from material licensed 6 | # to the University of California by American Telephone and Telegraph 7 | # Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 | # the permission of UNIX System Laboratories, Inc. 9 | # 10 | # Redistribution and use in source and binary forms, with or without 11 | # modification, are permitted provided that the following conditions 12 | # are met: 13 | # 1. Redistributions of source code must retain the above copyright 14 | # notice, this list of conditions and the following disclaimer. 15 | # 2. Redistributions in binary form must reproduce the above copyright 16 | # notice, this list of conditions and the following disclaimer in the 17 | # documentation and/or other materials provided with the distribution. 18 | # 3. The names of its contributors may not be used to endorse or promote 19 | # products derived from this software without specific prior written 20 | # permission. 21 | # 22 | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | # SUCH DAMAGE. 33 | # 34 | 35 | set(SOURCE 36 | ${SOURCE} 37 | ${CMAKE_CURRENT_SOURCE_DIR}/ppc403ga/io.c 38 | ${CMAKE_CURRENT_SOURCE_DIR}/ppc403ga/platform.c 39 | ${CMAKE_CURRENT_SOURCE_DIR}/ppc403ga/start.S 40 | PARENT_SCOPE) 41 | 42 | set(HEADERS 43 | ${HEADERS} 44 | ${CMAKE_CURRENT_SOURCE_DIR}/io.h 45 | ${CMAKE_CURRENT_SOURCE_DIR}/platform.h 46 | PARENT_SCOPE) 47 | -------------------------------------------------------------------------------- /loader/src/arch/io.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013 3 | * Benjamin Vanheuverzwijn 4 | * 5 | * All or some portions of this file are derived from material licensed 6 | * to the University of California by American Telephone and Telegraph 7 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 | * the permission of UNIX System Laboratories, Inc. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. The names of its contributors may not be used to endorse or promote 19 | * products derived from this software without specific prior written 20 | * permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef IO_H 36 | #define IO_H 37 | 38 | int io_putchar(int c); 39 | int io_puts(const char *s); 40 | int io_puts(const char *s); 41 | 42 | #endif // IO_H 43 | -------------------------------------------------------------------------------- /loader/src/arch/platform.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013 3 | * Benjamin Vanheuverzwijn 4 | * 5 | * All or some portions of this file are derived from material licensed 6 | * to the University of California by American Telephone and Telegraph 7 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 | * the permission of UNIX System Laboratories, Inc. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. The names of its contributors may not be used to endorse or promote 19 | * products derived from this software without specific prior written 20 | * permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef PLATFORM_H 36 | #define PLATFORM_H 37 | 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /loader/src/arch/ppc403ga/io.c: -------------------------------------------------------------------------------- 1 | /** 2 | * io - do basic IO on serial port, mainly to support the klib 3 | * 4 | * Copyright (c) 2013 5 | * Benjamin Vanheuverzwijn 6 | * 7 | * All or some portions of this file are derived from material licensed 8 | * to the University of California by American Telephone and Telegraph 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 | * the permission of UNIX System Laboratories, Inc. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. The names of its contributors may not be used to endorse or promote 21 | * products derived from this software without specific prior written 22 | * permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 | * SUCH DAMAGE. 35 | */ 36 | 37 | #include "../io.h" 38 | 39 | int io_putchar(int c) { 40 | asm("li %%r4, 0\n\t" 41 | "lis %%r4, 0x4000\n\t" 42 | "loop_transmit_buffer_ready:\n\t" 43 | "lbz %%r5, 0(%%r4)\n\t" 44 | "andi. %%r5, %%r5, 0x04\n\t" 45 | "beq 0, loop_transmit_buffer_ready\n\t" 46 | "stb %[character], 9(%%r4)\n\t" 47 | : // output list 48 | : [character] "r" (c) // input list 49 | : "r4", "r5" // clobber list 50 | ); 51 | 52 | return c; 53 | } 54 | 55 | int io_puts(const char *s) { 56 | while(*s != '\0') { 57 | io_putchar(*(s++)); 58 | } 59 | 60 | return 1; 61 | } 62 | 63 | int io_getchar(void) { 64 | // TODO - fill me 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /loader/src/arch/ppc403ga/platform.c: -------------------------------------------------------------------------------- 1 | /** 2 | * platform - implement platform driver 3 | * 4 | * Copyright (c) 2013 5 | * Benjamin Vanheuverzwijn 6 | * 7 | * All or some portions of this file are derived from material licensed 8 | * to the University of California by American Telephone and Telegraph 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 | * the permission of UNIX System Laboratories, Inc. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. The names of its contributors may not be used to endorse or promote 21 | * products derived from this software without specific prior written 22 | * permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 | * SUCH DAMAGE. 35 | */ 36 | 37 | -------------------------------------------------------------------------------- /loader/src/arch/ppc403ga/start.S: -------------------------------------------------------------------------------- 1 | /** 2 | * start.S - Entry point 3 | * 4 | * Copyright (c) 2013 5 | * Benjamin Vanheuverzwijn 6 | * 7 | * All or some portions of this file are derived from material licensed 8 | * to the University of California by American Telephone and Telegraph 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 | * the permission of UNIX System Laboratories, Inc. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. The names of its contributors may not be used to endorse or promote 21 | * products derived from this software without specific prior written 22 | * permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 | * SUCH DAMAGE. 35 | */ 36 | 37 | .extern start_loader 38 | .global _start 39 | 40 | _start: 41 | # Store return address 42 | mflr %r0 43 | stw %r0, 8(%r1) 44 | 45 | # Jump to the second stage loader 46 | bl start_loader 47 | 48 | # Return to the bootloader 49 | lwz %r0, 8(%r1) 50 | mtlr %r0 51 | blr 52 | -------------------------------------------------------------------------------- /loader/src/klib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2013 3 | # Benjamin Vanheuverzwijn 4 | # 5 | # All or some portions of this file are derived from material licensed 6 | # to the University of California by American Telephone and Telegraph 7 | # Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 | # the permission of UNIX System Laboratories, Inc. 9 | # 10 | # Redistribution and use in source and binary forms, with or without 11 | # modification, are permitted provided that the following conditions 12 | # are met: 13 | # 1. Redistributions of source code must retain the above copyright 14 | # notice, this list of conditions and the following disclaimer. 15 | # 2. Redistributions in binary form must reproduce the above copyright 16 | # notice, this list of conditions and the following disclaimer in the 17 | # documentation and/or other materials provided with the distribution. 18 | # 3. The names of its contributors may not be used to endorse or promote 19 | # products derived from this software without specific prior written 20 | # permission. 21 | # 22 | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | # SUCH DAMAGE. 33 | # 34 | 35 | set(SOURCE 36 | ${SOURCE} 37 | ${CMAKE_CURRENT_SOURCE_DIR}/memchr.c 38 | ${CMAKE_CURRENT_SOURCE_DIR}/printf.c 39 | ${CMAKE_CURRENT_SOURCE_DIR}/strlen.c 40 | PARENT_SCOPE) 41 | 42 | set(HEADERS 43 | ${HEADERS} 44 | ${CMAKE_CURRENT_SOURCE_DIR}/klib.h 45 | PARENT_SCOPE) 46 | -------------------------------------------------------------------------------- /loader/src/klib/klib.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013 3 | * Benjamin Vanheuverzwijn 4 | * 5 | * All or some portions of this file are derived from material licensed 6 | * to the University of California by American Telephone and Telegraph 7 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 | * the permission of UNIX System Laboratories, Inc. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. The names of its contributors may not be used to endorse or promote 19 | * products derived from this software without specific prior written 20 | * permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef KLIB_H 36 | #define KLIB_H 37 | 38 | #ifndef NULL 39 | #define NULL 0 40 | #endif 41 | 42 | void *memchr(const void *s, int c, int n); 43 | int strlen(const char *str); 44 | 45 | int printf(const char *fmt, ...); 46 | 47 | #endif // KLIB_H 48 | -------------------------------------------------------------------------------- /loader/src/klib/memchr.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 1990, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * Copyright (c) 2013 5 | * Benjamin Vanheuverzwijn 6 | * 7 | * This code is derived from software contributed to Berkeley by 8 | * Chris Torek. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 4. Neither the name of the University nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | */ 34 | 35 | #include "klib.h" 36 | 37 | void * 38 | memchr(const void *s, int c, int n) 39 | { 40 | if (n != 0) { 41 | const unsigned char *p = s; 42 | 43 | do { 44 | if (*p++ == (unsigned char)c) 45 | return ((void *)(unsigned int *)(p - 1)); 46 | } while (--n != 0); 47 | } 48 | return (NULL); 49 | } 50 | -------------------------------------------------------------------------------- /loader/src/klib/printf.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 1986, 1988, 1991, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * (c) UNIX System Laboratories, Inc. 5 | * Copyright (c) 2013 6 | * Benjamin Vanheuverzwijn 7 | * 8 | * All or some portions of this file are derived from material licensed 9 | * to the University of California by American Telephone and Telegraph 10 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 11 | * the permission of UNIX System Laboratories, Inc. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions 15 | * are met: 16 | * 1. Redistributions of source code must retain the above copyright 17 | * notice, this list of conditions and the following disclaimer. 18 | * 2. Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * 3. Neither the name of the University nor the names of its contributors 22 | * may be used to endorse or promote products derived from this software 23 | * without specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 | * SUCH DAMAGE. 36 | */ 37 | 38 | #include 39 | 40 | #include "../arch/io.h" 41 | #include "klib.h" 42 | 43 | typedef unsigned int size_t; 44 | typedef int ssize_t; 45 | 46 | typedef unsigned long long u_quad_t; 47 | typedef long long quad_t; 48 | 49 | typedef unsigned short u_short; 50 | typedef unsigned int u_int; 51 | typedef unsigned long u_long; 52 | 53 | /* 54 | * defines 55 | */ 56 | 57 | /* flags for kprintf */ 58 | #define TOCONS 0x01 /* to the console */ 59 | #define TOTTY 0x02 /* to the process' tty */ 60 | #define TOLOG 0x04 /* to the kernel message buffer */ 61 | #define TOBUFONLY 0x08 /* to the buffer (only) [for snprintf] */ 62 | #define TODDB 0x10 /* to ddb console */ 63 | #define TOCOUNT 0x20 /* act like [v]snprintf */ 64 | 65 | /* max size buffer kprintf needs to print quad_t [size in base 8 + \0] */ 66 | #define KPRINTF_BUFSIZE (sizeof(quad_t) * 8 / 3 + 2) 67 | 68 | 69 | /* 70 | * local prototypes 71 | */ 72 | 73 | int kprintf(const char *, int, void *, char *, va_list); 74 | 75 | /* 76 | * normal kernel printf functions: printf, vprintf, snprintf 77 | */ 78 | 79 | /* 80 | * printf: print a message to the console and the log 81 | */ 82 | int 83 | printf(const char *fmt, ...) 84 | { 85 | va_list ap; 86 | int retval; 87 | 88 | va_start(ap, fmt); 89 | retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap); 90 | va_end(ap); 91 | 92 | return(retval); 93 | } 94 | 95 | /* 96 | * vprintf: print a message to the console and the log [already have a 97 | * va_list] 98 | */ 99 | 100 | int 101 | vprintf(const char *fmt, va_list ap) 102 | { 103 | int retval; 104 | 105 | retval = kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap); 106 | 107 | return (retval); 108 | } 109 | 110 | /* 111 | * snprintf: print a message to a buffer 112 | */ 113 | int 114 | snprintf(char *buf, size_t size, const char *fmt, ...) 115 | { 116 | int retval; 117 | va_list ap; 118 | char *p; 119 | 120 | p = buf + size - 1; 121 | if (size < 1) 122 | p = buf; 123 | va_start(ap, fmt); 124 | retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap); 125 | va_end(ap); 126 | if (size > 0) 127 | *(p) = 0; /* null terminate */ 128 | return(retval); 129 | } 130 | 131 | /* 132 | * vsnprintf: print a message to a buffer [already have va_alist] 133 | */ 134 | int 135 | vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) 136 | { 137 | int retval; 138 | char *p; 139 | 140 | p = buf + size - 1; 141 | if (size < 1) 142 | p = buf; 143 | retval = kprintf(fmt, TOBUFONLY | TOCOUNT, &p, buf, ap); 144 | if (size > 0) 145 | *(p) = 0; /* null terminate */ 146 | return(retval); 147 | } 148 | 149 | /* 150 | * kprintf: scaled down version of printf(3). 151 | * 152 | * this version based on vfprintf() from libc which was derived from 153 | * software contributed to Berkeley by Chris Torek. 154 | * 155 | * The additional format %b is supported to decode error registers. 156 | * Its usage is: 157 | * 158 | * printf("reg=%b\n", regval, "*"); 159 | * 160 | * where is the output base expressed as a control character, e.g. 161 | * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, 162 | * the first of which gives the bit number to be inspected (origin 1), and 163 | * the next characters (up to a control character, i.e. a character <= 32), 164 | * give the name of the register. Thus: 165 | * 166 | * kprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 167 | * 168 | * would produce output: 169 | * 170 | * reg=3 171 | * 172 | * To support larger integers (> 32 bits), %b formatting will also accept 173 | * control characters in the region 0x80 - 0xff. 0x80 refers to bit 0, 174 | * 0x81 refers to bit 1, and so on. The equivalent string to the above is: 175 | * 176 | * kprintf("reg=%b\n", 3, "\10\201BITTWO\200BITONE\n"); 177 | * 178 | * and would produce the same output. 179 | * 180 | * Like the rest of printf, %b can be prefixed to handle various size 181 | * modifiers, eg. %b is for "int", %lb is for "long", and %llb supports 182 | * "long long". 183 | * 184 | * This code is large and complicated... 185 | */ 186 | 187 | /* 188 | * macros for converting digits to letters and vice versa 189 | */ 190 | #define to_digit(c) ((c) - '0') 191 | #define is_digit(c) ((unsigned)to_digit(c) <= 9) 192 | #define to_char(n) ((n) + '0') 193 | 194 | /* 195 | * flags used during conversion. 196 | */ 197 | #define ALT 0x001 /* alternate form */ 198 | #define HEXPREFIX 0x002 /* add 0x or 0X prefix */ 199 | #define LADJUST 0x004 /* left adjustment */ 200 | #define LONGDBL 0x008 /* long double; unimplemented */ 201 | #define LONGINT 0x010 /* long integer */ 202 | #define QUADINT 0x020 /* quad integer */ 203 | #define SHORTINT 0x040 /* short integer */ 204 | #define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ 205 | #define FPT 0x100 /* Floating point number */ 206 | #define SIZEINT 0x200 /* (signed) size_t */ 207 | 208 | /* 209 | * To extend shorts properly, we need both signed and unsigned 210 | * argument extraction methods. 211 | */ 212 | #define SARG() \ 213 | (flags&QUADINT ? va_arg(ap, quad_t) : \ 214 | flags&LONGINT ? va_arg(ap, long) : \ 215 | flags&SIZEINT ? va_arg(ap, ssize_t) : \ 216 | flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ 217 | (long)va_arg(ap, int)) 218 | #define UARG() \ 219 | (flags&QUADINT ? va_arg(ap, u_quad_t) : \ 220 | flags&LONGINT ? va_arg(ap, u_long) : \ 221 | flags&SIZEINT ? va_arg(ap, size_t) : \ 222 | flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ 223 | (u_long)va_arg(ap, u_int)) 224 | 225 | #define KPRINTF_PUTCHAR(C) do { \ 226 | int chr = (C); \ 227 | ret += 1; \ 228 | if (oflags & TOBUFONLY) { \ 229 | if ((vp != NULL) && (sbuf == tailp)) { \ 230 | if (!(oflags & TOCOUNT)) \ 231 | goto overflow; \ 232 | } else \ 233 | *sbuf++ = chr; \ 234 | } else { \ 235 | io_putchar(chr); \ 236 | } \ 237 | } while(0) 238 | 239 | int 240 | kprintf(const char *fmt0, int oflags, void *vp, char *sbuf, va_list ap) 241 | { 242 | char *fmt; /* format string */ 243 | int ch; /* character from fmt */ 244 | int n; /* handy integer (short term usage) */ 245 | char *cp = NULL; /* handy char pointer (short term usage) */ 246 | int flags; /* flags as above */ 247 | int ret; /* return value accumulator */ 248 | int width; /* width from format (%8d), or 0 */ 249 | int prec; /* precision from format (%.3d), or -1 */ 250 | char sign; /* sign prefix (' ', '+', '-', or \0) */ 251 | 252 | u_quad_t _uquad; /* integer arguments %[diouxX] */ 253 | enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */ 254 | int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 255 | int realsz; /* field size expanded by dprec */ 256 | int size = 0; /* size of converted field or string */ 257 | char *xdigs = NULL; /* digits for [xX] conversion */ 258 | char buf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */ 259 | char *tailp = NULL; /* tail pointer for snprintf */ 260 | 261 | if ((oflags & TOBUFONLY) && (vp != NULL)) 262 | tailp = *(char **)vp; 263 | 264 | fmt = (char *)fmt0; 265 | ret = 0; 266 | 267 | /* 268 | * Scan the format for conversions (`%' character). 269 | */ 270 | for (;;) { 271 | while (*fmt != '%' && *fmt) { 272 | KPRINTF_PUTCHAR(*fmt++); 273 | } 274 | if (*fmt == 0) 275 | goto done; 276 | 277 | fmt++; /* skip over '%' */ 278 | 279 | flags = 0; 280 | dprec = 0; 281 | width = 0; 282 | prec = -1; 283 | sign = '\0'; 284 | 285 | rflag: ch = *fmt++; 286 | reswitch: switch (ch) { 287 | /* XXX: non-standard '%b' format */ 288 | case 'b': { 289 | char *b, *z; 290 | int tmp; 291 | _uquad = UARG(); 292 | b = va_arg(ap, char *); 293 | if (*b == 8) 294 | snprintf(buf, sizeof buf, "%llo", _uquad); 295 | else if (*b == 10) 296 | snprintf(buf, sizeof buf, "%lld", _uquad); 297 | else if (*b == 16) 298 | snprintf(buf, sizeof buf, "%llx", _uquad); 299 | else 300 | break; 301 | b++; 302 | 303 | z = buf; 304 | while (*z) { 305 | KPRINTF_PUTCHAR(*z++); 306 | } 307 | 308 | if (_uquad) { 309 | tmp = 0; 310 | while ((n = *b++) != 0) { 311 | if (n & 0x80) 312 | n &= 0x7f; 313 | else if (n <= ' ') 314 | n = n - 1; 315 | if (_uquad & (1LL << n)) { 316 | KPRINTF_PUTCHAR(tmp ? ',':'<'); 317 | while (*b > ' ' && 318 | (*b & 0x80) == 0) { 319 | KPRINTF_PUTCHAR(*b); 320 | b++; 321 | } 322 | tmp = 1; 323 | } else { 324 | while (*b > ' ' && 325 | (*b & 0x80) == 0) 326 | b++; 327 | } 328 | } 329 | if (tmp) { 330 | KPRINTF_PUTCHAR('>'); 331 | } 332 | } 333 | continue; /* no output */ 334 | } 335 | 336 | case ' ': 337 | /* 338 | * ``If the space and + flags both appear, the space 339 | * flag will be ignored.'' 340 | * -- ANSI X3J11 341 | */ 342 | if (!sign) 343 | sign = ' '; 344 | goto rflag; 345 | case '#': 346 | flags |= ALT; 347 | goto rflag; 348 | case '*': 349 | /* 350 | * ``A negative field width argument is taken as a 351 | * - flag followed by a positive field width.'' 352 | * -- ANSI X3J11 353 | * They don't exclude field widths read from args. 354 | */ 355 | if ((width = va_arg(ap, int)) >= 0) 356 | goto rflag; 357 | width = -width; 358 | /* FALLTHROUGH */ 359 | case '-': 360 | flags |= LADJUST; 361 | goto rflag; 362 | case '+': 363 | sign = '+'; 364 | goto rflag; 365 | case '.': 366 | if ((ch = *fmt++) == '*') { 367 | n = va_arg(ap, int); 368 | prec = n < 0 ? -1 : n; 369 | goto rflag; 370 | } 371 | n = 0; 372 | while (is_digit(ch)) { 373 | n = 10 * n + to_digit(ch); 374 | ch = *fmt++; 375 | } 376 | prec = n < 0 ? -1 : n; 377 | goto reswitch; 378 | case '0': 379 | /* 380 | * ``Note that 0 is taken as a flag, not as the 381 | * beginning of a field width.'' 382 | * -- ANSI X3J11 383 | */ 384 | flags |= ZEROPAD; 385 | goto rflag; 386 | case '1': case '2': case '3': case '4': 387 | case '5': case '6': case '7': case '8': case '9': 388 | n = 0; 389 | do { 390 | n = 10 * n + to_digit(ch); 391 | ch = *fmt++; 392 | } while (is_digit(ch)); 393 | width = n; 394 | goto reswitch; 395 | case 'h': 396 | flags |= SHORTINT; 397 | goto rflag; 398 | case 'l': 399 | if (*fmt == 'l') { 400 | fmt++; 401 | flags |= QUADINT; 402 | } else { 403 | flags |= LONGINT; 404 | } 405 | goto rflag; 406 | case 'q': 407 | flags |= QUADINT; 408 | goto rflag; 409 | case 'z': 410 | flags |= SIZEINT; 411 | goto rflag; 412 | case 'c': 413 | *(cp = buf) = va_arg(ap, int); 414 | size = 1; 415 | sign = '\0'; 416 | break; 417 | case 'D': 418 | flags |= LONGINT; 419 | /*FALLTHROUGH*/ 420 | case 'd': 421 | case 'i': 422 | _uquad = SARG(); 423 | if ((quad_t)_uquad < 0) { 424 | _uquad = -_uquad; 425 | sign = '-'; 426 | } 427 | base = DEC; 428 | goto number; 429 | case 'n': 430 | if (flags & QUADINT) 431 | *va_arg(ap, quad_t *) = ret; 432 | else if (flags & LONGINT) 433 | *va_arg(ap, long *) = ret; 434 | else if (flags & SHORTINT) 435 | *va_arg(ap, short *) = ret; 436 | else if (flags & SIZEINT) 437 | *va_arg(ap, ssize_t *) = ret; 438 | else 439 | *va_arg(ap, int *) = ret; 440 | continue; /* no output */ 441 | case 'O': 442 | flags |= LONGINT; 443 | /*FALLTHROUGH*/ 444 | case 'o': 445 | _uquad = UARG(); 446 | base = OCT; 447 | goto nosign; 448 | case 'p': 449 | /* 450 | * ``The argument shall be a pointer to void. The 451 | * value of the pointer is converted to a sequence 452 | * of printable characters, in an implementation- 453 | * defined manner.'' 454 | * -- ANSI X3J11 455 | */ 456 | /* NOSTRICT */ 457 | _uquad = (u_long)va_arg(ap, void *); 458 | base = HEX; 459 | xdigs = "0123456789abcdef"; 460 | flags |= HEXPREFIX; 461 | ch = 'x'; 462 | goto nosign; 463 | case 's': 464 | if ((cp = va_arg(ap, char *)) == NULL) 465 | cp = "(null)"; 466 | if (prec >= 0) { 467 | /* 468 | * can't use strlen; can only look for the 469 | * NUL in the first `prec' characters, and 470 | * strlen() will go further. 471 | */ 472 | char *p = memchr(cp, 0, prec); 473 | 474 | if (p != NULL) { 475 | size = p - cp; 476 | if (size > prec) 477 | size = prec; 478 | } else 479 | size = prec; 480 | } else 481 | size = strlen(cp); 482 | sign = '\0'; 483 | break; 484 | case 'U': 485 | flags |= LONGINT; 486 | /*FALLTHROUGH*/ 487 | case 'u': 488 | _uquad = UARG(); 489 | base = DEC; 490 | goto nosign; 491 | case 'X': 492 | xdigs = "0123456789ABCDEF"; 493 | goto hex; 494 | case 'x': 495 | xdigs = "0123456789abcdef"; 496 | hex: _uquad = UARG(); 497 | base = HEX; 498 | /* leading 0x/X only if non-zero */ 499 | if (flags & ALT && _uquad != 0) 500 | flags |= HEXPREFIX; 501 | 502 | /* unsigned conversions */ 503 | nosign: sign = '\0'; 504 | /* 505 | * ``... diouXx conversions ... if a precision is 506 | * specified, the 0 flag will be ignored.'' 507 | * -- ANSI X3J11 508 | */ 509 | number: if ((dprec = prec) >= 0) 510 | flags &= ~ZEROPAD; 511 | 512 | /* 513 | * ``The result of converting a zero value with an 514 | * explicit precision of zero is no characters.'' 515 | * -- ANSI X3J11 516 | */ 517 | cp = buf + KPRINTF_BUFSIZE; 518 | if (_uquad != 0 || prec != 0) { 519 | /* 520 | * Unsigned mod is hard, and unsigned mod 521 | * by a constant is easier than that by 522 | * a variable; hence this switch. 523 | */ 524 | switch (base) { 525 | case OCT: 526 | do { 527 | *--cp = to_char(_uquad & 7); 528 | _uquad >>= 3; 529 | } while (_uquad); 530 | /* handle octal leading 0 */ 531 | if (flags & ALT && *cp != '0') 532 | *--cp = '0'; 533 | break; 534 | 535 | case DEC: 536 | /* many numbers are 1 digit */ 537 | while (_uquad >= 10) { 538 | *--cp = to_char(_uquad % 10); 539 | _uquad /= 10; 540 | } 541 | *--cp = to_char(_uquad); 542 | break; 543 | 544 | case HEX: 545 | do { 546 | *--cp = xdigs[_uquad & 15]; 547 | _uquad >>= 4; 548 | } while (_uquad); 549 | break; 550 | 551 | default: 552 | cp = "bug in kprintf: bad base"; 553 | size = strlen(cp); 554 | goto skipsize; 555 | } 556 | } 557 | size = buf + KPRINTF_BUFSIZE - cp; 558 | skipsize: 559 | break; 560 | default: /* "%?" prints ?, unless ? is NUL */ 561 | if (ch == '\0') 562 | goto done; 563 | /* pretend it was %c with argument ch */ 564 | cp = buf; 565 | *cp = ch; 566 | size = 1; 567 | sign = '\0'; 568 | break; 569 | } 570 | 571 | /* 572 | * All reasonable formats wind up here. At this point, `cp' 573 | * points to a string which (if not flags&LADJUST) should be 574 | * padded out to `width' places. If flags&ZEROPAD, it should 575 | * first be prefixed by any sign or other prefix; otherwise, 576 | * it should be blank padded before the prefix is emitted. 577 | * After any left-hand padding and prefixing, emit zeroes 578 | * required by a decimal [diouxX] precision, then print the 579 | * string proper, then emit zeroes required by any leftover 580 | * floating precision; finally, if LADJUST, pad with blanks. 581 | * 582 | * Compute actual size, so we know how much to pad. 583 | * size excludes decimal prec; realsz includes it. 584 | */ 585 | realsz = dprec > size ? dprec : size; 586 | if (sign) 587 | realsz++; 588 | else if (flags & HEXPREFIX) 589 | realsz+= 2; 590 | 591 | /* right-adjusting blank padding */ 592 | if ((flags & (LADJUST|ZEROPAD)) == 0) { 593 | n = width - realsz; 594 | while (n-- > 0) 595 | KPRINTF_PUTCHAR(' '); 596 | } 597 | 598 | /* prefix */ 599 | if (sign) { 600 | KPRINTF_PUTCHAR(sign); 601 | } else if (flags & HEXPREFIX) { 602 | KPRINTF_PUTCHAR('0'); 603 | KPRINTF_PUTCHAR(ch); 604 | } 605 | 606 | /* right-adjusting zero padding */ 607 | if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) { 608 | n = width - realsz; 609 | while (n-- > 0) 610 | KPRINTF_PUTCHAR('0'); 611 | } 612 | 613 | /* leading zeroes from decimal precision */ 614 | n = dprec - size; 615 | while (n-- > 0) 616 | KPRINTF_PUTCHAR('0'); 617 | 618 | /* the string or number proper */ 619 | while (size--) 620 | KPRINTF_PUTCHAR(*cp++); 621 | /* left-adjusting padding (always blank) */ 622 | if (flags & LADJUST) { 623 | n = width - realsz; 624 | while (n-- > 0) 625 | KPRINTF_PUTCHAR(' '); 626 | } 627 | } 628 | 629 | done: 630 | if ((oflags & TOBUFONLY) && (vp != NULL)) 631 | *(char **)vp = sbuf; 632 | overflow: 633 | return (ret); 634 | /* NOTREACHED */ 635 | } 636 | 637 | -------------------------------------------------------------------------------- /loader/src/klib/strlen.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 1990, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * Copyright (c) 2013 5 | * Benjamin Vanheuverzwijn 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 4. Neither the name of the University nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #include "klib.h" 33 | 34 | int 35 | strlen(str) 36 | const char *str; 37 | { 38 | register const char *s; 39 | 40 | for (s = str; *s; ++s); 41 | return(s - str); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /loader/src/main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Loader - bootstrapped from arch/.../start.S 3 | * 4 | * Copyright (c) 2013 5 | * Benjamin Vanheuverzwijn 6 | * 7 | * All or some portions of this file are derived from material licensed 8 | * to the University of California by American Telephone and Telegraph 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 | * the permission of UNIX System Laboratories, Inc. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions 14 | * are met: 15 | * 1. Redistributions of source code must retain the above copyright 16 | * notice, this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * 3. The names of its contributors may not be used to endorse or promote 21 | * products derived from this software without specific prior written 22 | * permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 | * SUCH DAMAGE. 35 | */ 36 | 37 | #include "klib/klib.h" 38 | 39 | int start_loader() { 40 | printf("Hello, Cisco!\n"); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /mziptools/Makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bvanheu/linux-cisco/5d5c1d7333c632b9f7ba51ffa30206fde7ce97c8/mziptools/Makefile -------------------------------------------------------------------------------- /mziptools/README: -------------------------------------------------------------------------------- 1 | How to build? 2 | ~~~~~~~~~~~~~ 3 | > elf2mzip 4 | $ gcc -l zip -o elf2mzip crc16.c mzip.c elf2mzip.c 5 | 6 | > readmzip 7 | $ gcc -l zip -o readmzip crc16.c mzip.c readmzip.c 8 | -------------------------------------------------------------------------------- /mziptools/crc16.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012, Benjamin Vanheuverzwijn 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include 29 | 30 | #include "crc16.h" 31 | 32 | static const uint16_t crc16_ccitt_table[256]= { 33 | 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 34 | 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 35 | 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 36 | 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, 37 | 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, 38 | 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, 39 | 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, 40 | 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, 41 | 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, 42 | 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, 43 | 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, 44 | 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, 45 | 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, 46 | 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, 47 | 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, 48 | 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, 49 | 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, 50 | 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, 51 | 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, 52 | 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, 53 | 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, 54 | 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, 55 | 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, 56 | 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, 57 | 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, 58 | 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, 59 | 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, 60 | 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, 61 | 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, 62 | 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, 63 | 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, 64 | 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0, 65 | }; 66 | 67 | uint16_t crc16_ccitt(const uint8_t *buffer, size_t size, uint16_t remainder) 68 | { 69 | uint16_t crc = ~remainder; 70 | size_t i; 71 | 72 | for (i=0; i < size; i++) { 73 | crc = (crc << 8) ^ crc16_ccitt_table[((crc >> 8) ^ ((uint8_t *)buffer)[i]) & 0xFF]; 74 | } 75 | 76 | return ~crc; 77 | } 78 | -------------------------------------------------------------------------------- /mziptools/crc16.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012, Benjamin Vanheuverzwijn 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __CRC16_H 29 | #define __CRC16_H 30 | 31 | #include 32 | #include 33 | 34 | uint16_t crc16_ccitt(const uint8_t *buffer, size_t size, uint16_t remainder); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /mziptools/elf2mzip.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012, Benjamin Vanheuverzwijn 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #define _BSD_SOURCE 29 | 30 | #include // FIXME - linux only :( 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "mzip.h" 43 | 44 | static inline void elf_header_to_littleendian(Elf32_Ehdr *elf) { 45 | elf->e_type = be16toh(elf->e_type); 46 | elf->e_machine = be16toh(elf->e_machine); 47 | elf->e_version = be32toh(elf->e_version); 48 | elf->e_entry = be32toh(elf->e_entry); 49 | elf->e_phoff = be32toh(elf->e_phoff); 50 | elf->e_shoff = be32toh(elf->e_shoff); 51 | elf->e_flags = be32toh(elf->e_flags); 52 | elf->e_ehsize = be16toh(elf->e_ehsize); 53 | elf->e_phentsize = be16toh(elf->e_phentsize); 54 | elf->e_phnum = be16toh(elf->e_phnum); 55 | elf->e_shentsize = be16toh(elf->e_shentsize); 56 | elf->e_shnum = be16toh(elf->e_shnum); 57 | elf->e_shstrndx = be16toh(elf->e_shstrndx); 58 | } 59 | 60 | static inline void elf_program_header_to_littleendian(Elf32_Phdr *ph) { 61 | ph->p_type = be32toh(ph->p_type); 62 | ph->p_flags = be32toh(ph->p_flags); 63 | ph->p_offset = be32toh(ph->p_offset); 64 | ph->p_vaddr = be32toh(ph->p_vaddr); 65 | ph->p_filesz = be32toh(ph->p_filesz); 66 | ph->p_memsz = be32toh(ph->p_memsz); 67 | ph->p_flags = be32toh(ph->p_flags); 68 | ph->p_align = be32toh(ph->p_align); 69 | } 70 | 71 | int usage() { 72 | printf("Usage: elf2mzip input_file output_file\n"); 73 | return 0; 74 | } 75 | 76 | int main(int argc, char *argv[]) { 77 | Elf32_Ehdr elf; 78 | size_t bytes_read; 79 | uint8_t i; 80 | int fd; 81 | Elf32_Phdr *program_header_table; 82 | mzip_t *mzip = mzip_create(); 83 | bool elf_in_bigendian = false; 84 | 85 | if (argc != 3) { 86 | usage(); 87 | return EXIT_FAILURE; 88 | } 89 | 90 | fd = open(argv[1], O_RDONLY); 91 | bytes_read = read(fd, (uint8_t *)&elf, sizeof(Elf32_Ehdr)); 92 | 93 | // Validate ELF file 94 | if (elf.e_ident[EI_MAG0] != ELFMAG0 || elf.e_ident[EI_MAG1] != ELFMAG1 || elf.e_ident[EI_MAG2] != ELFMAG2 || elf.e_ident[EI_MAG3] != ELFMAG3) { 95 | // TODO - error 96 | fprintf(stderr, "error - not an ELF file\n"); 97 | return EXIT_FAILURE; 98 | } 99 | 100 | // Validate endianess 101 | if (elf.e_ident[EI_DATA] == ELFDATA2MSB) { 102 | elf_in_bigendian = true; 103 | elf_header_to_littleendian(&elf); 104 | } 105 | 106 | // Validate entry point 107 | if (elf.e_entry < 0x3000) { 108 | // TODO - error 109 | fprintf(stderr, "error - invalid entry point: %x (to be valid: 0x3000 < entry_point < 0x10000)", elf.e_entry); 110 | return EXIT_FAILURE; 111 | } 112 | printf("\tEntry point: 0x%x\n", elf.e_entry); 113 | 114 | // Validate at least one program header 115 | if (!elf.e_phnum) { 116 | // TODO - error 117 | fprintf(stderr, "error - no program header: %d\n", elf.e_phnum); 118 | return EXIT_FAILURE; 119 | } 120 | 121 | printf("\tProgram header segment: %d\n", elf.e_phnum); 122 | 123 | // Seek to program header tables 124 | if (lseek(fd, elf.e_phoff, SEEK_SET) < 0) { 125 | // TODO - error 126 | fprintf(stderr, "error - unable to seek to program header table\n"); 127 | return EXIT_FAILURE; 128 | } 129 | 130 | program_header_table = (Elf32_Phdr *)malloc(elf.e_phnum * elf.e_phentsize); 131 | 132 | bytes_read = read(fd, program_header_table, elf.e_phnum * elf.e_phentsize); 133 | if (bytes_read != elf.e_phnum * elf.e_phentsize) { 134 | // TODO - error; 135 | fprintf(stderr, "error - unable to read program header table\n"); 136 | return EXIT_FAILURE; 137 | } 138 | 139 | uint8_t *program_section; 140 | for (i=0; i < elf.e_phnum; i++) { 141 | if (elf_in_bigendian) { 142 | elf_program_header_to_littleendian(&(program_header_table[i])); 143 | } 144 | 145 | printf("\t\tPROGRAM SEGMENT %d\n", i); 146 | 147 | // Keep only LOAD program segment 148 | if (program_header_table[i].p_type != PT_LOAD) { 149 | printf("\t\tSkipping non PT_LOAD segment\n"); 150 | continue; 151 | } 152 | 153 | printf("\t\tSegment type:\t\tPT_LOAD\n"); 154 | printf("\t\tSegment load address:\t0x%x\n", program_header_table[i].p_vaddr); 155 | printf("\t\tSegment size:\t\t0x%x\n", program_header_table[i].p_filesz); 156 | printf("\t\tMemory image size:\t0x%x\n", program_header_table[i].p_memsz); 157 | 158 | if (lseek(fd, program_header_table[i].p_offset, SEEK_SET) < 0) { 159 | // TODO - error 160 | fprintf(stderr, "error - unable to seek to program_header_table\n"); 161 | continue; 162 | } 163 | 164 | program_section = (uint8_t *)malloc(program_header_table[i].p_filesz); 165 | 166 | bytes_read = read(fd, program_section, program_header_table[i].p_filesz); 167 | if (bytes_read != program_header_table[i].p_filesz) { 168 | // TODO - error 169 | fprintf(stderr, "error - unable to read enough bytes\n"); 170 | continue; 171 | } 172 | 173 | 174 | // XXX - For now, we only keep the first LOAD program segment 175 | break; 176 | } 177 | 178 | if (program_section == NULL) { 179 | // TODO - error 180 | fprintf(stderr, "error - no program segment PT_LOAD found\n"); 181 | return EXIT_FAILURE; 182 | } 183 | 184 | mzip_add_segment(mzip, program_header_table[i].p_vaddr, program_section, program_header_table[i].p_filesz, program_header_table[i].p_memsz); 185 | mzip_compress_segment(mzip); 186 | mzip_set_entry_point(mzip, elf.e_entry); 187 | mzip_save(mzip, argv[2]); 188 | mzip_destroy(mzip); 189 | 190 | close(fd); 191 | 192 | return EXIT_SUCCESS; 193 | } 194 | -------------------------------------------------------------------------------- /mziptools/mzip.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012, Benjamin Vanheuverzwijn 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #include "mzip.h" 39 | #include "crc16.h" 40 | 41 | static inline void mzip_header_host_to_bigendian(mzip_header_t *header) { 42 | header->magic = htobe32(header->magic); 43 | header->version = htobe32(header->version); 44 | header->entry_point = htobe32(header->entry_point); 45 | header->unknown1 = htobe32(header->unknown1); 46 | header->unknown2 = htobe32(header->unknown2); 47 | header->segment_crc16 = htobe16(header->segment_crc16); 48 | header->header_crc16 = htobe16(header->header_crc16); 49 | header->header_size = htobe32(header->header_size); 50 | header->load_address = htobe32(header->load_address); 51 | header->segment_type = htobe32(header->segment_type); 52 | header->segment_compressed_size = htobe32(header->segment_compressed_size); 53 | header->segment_size = htobe32(header->segment_size); 54 | header->memory_image_size = htobe32(header->memory_image_size); 55 | } 56 | 57 | static inline void mzip_header_bigendian_to_host(mzip_header_t *header) { 58 | header->magic = be32toh(header->magic); 59 | header->version = be32toh(header->version); 60 | header->entry_point = be32toh(header->entry_point); 61 | header->unknown1 = be32toh(header->unknown1); 62 | header->unknown2 = be32toh(header->unknown2); 63 | header->segment_crc16 = be16toh(header->segment_crc16); 64 | header->header_crc16 = be16toh(header->header_crc16); 65 | header->header_size = be32toh(header->header_size); 66 | header->load_address = be32toh(header->load_address); 67 | header->segment_type = be32toh(header->segment_type); 68 | header->segment_compressed_size = be32toh(header->segment_compressed_size); 69 | header->segment_size = be32toh(header->segment_size); 70 | header->memory_image_size = be32toh(header->memory_image_size); 71 | } 72 | 73 | // 74 | // MZIP header 75 | // 76 | mzip_header_t *mzip_header_new() { 77 | mzip_header_t *m = (mzip_header_t *)malloc(sizeof(mzip_header_t)); 78 | 79 | memset((void *)m, '\x00', sizeof(mzip_header_t)); 80 | 81 | return m; 82 | } 83 | 84 | void mzip_header_free(mzip_header_t *m) { 85 | if (m != NULL) { 86 | free(m); 87 | } 88 | } 89 | 90 | 91 | // 92 | // MZIP file 93 | // 94 | mzip_t *mzip_open(const char *filename) { 95 | ssize_t bytes_read; 96 | int fd; 97 | 98 | mzip_t *m = (mzip_t *)malloc(sizeof(mzip_t)); 99 | m->header = (mzip_header_t *)malloc(sizeof(mzip_header_t)); 100 | 101 | fd = open(filename, O_RDONLY); 102 | if (fd < 0) { 103 | // TODO - error 104 | return NULL; 105 | } 106 | 107 | bytes_read = read(fd, (void *)m->header, sizeof(mzip_header_t)); 108 | if (bytes_read != sizeof(mzip_header_t)) { 109 | // TODO - error 110 | } 111 | 112 | mzip_header_bigendian_to_host(m->header); 113 | 114 | switch (m->header->segment_type) { 115 | case MZIP_SEGMENT_TYPE_UNKNOWN: 116 | m->segment_buffer_size = m->header->segment_size; 117 | break; 118 | case MZIP_SEGMENT_TYPE_PKZIP: 119 | m->segment_buffer_size = m->header->segment_compressed_size; 120 | break; 121 | default: 122 | // TODO - error unsupported segment type 123 | break; 124 | } 125 | 126 | m->segment = (uint8_t *)malloc(sizeof(m->segment_buffer_size)); 127 | bytes_read = read(fd, (void *)m->segment, m->segment_buffer_size); 128 | if (bytes_read != m->segment_buffer_size) { 129 | // TODO - error 130 | } 131 | 132 | close(fd); 133 | 134 | return m; 135 | } 136 | 137 | /** 138 | * Free some memory 139 | */ 140 | void mzip_close(mzip_t *m) { 141 | if (m != NULL) { 142 | if (m->header != NULL) { 143 | free(m->header); 144 | } 145 | if (m->segment != NULL) { 146 | free(m->segment); 147 | } 148 | free(m); 149 | } 150 | } 151 | 152 | /** 153 | * Create a MZIP file 154 | */ 155 | mzip_t *mzip_create(void) { 156 | mzip_t *m = (mzip_t *)malloc(sizeof(mzip_t)); 157 | m->header = mzip_header_new(); 158 | 159 | m->header->magic = MZIP_HEADER_MAGIC; 160 | m->header->version = MZIP_HEADER_VERSION_1; 161 | // next two values must be 0x1 i don't know why. 162 | m->header->unknown1 = 0x1; 163 | m->header->unknown2 = 0x1; 164 | 165 | m->header->header_size = sizeof(mzip_header_t); 166 | 167 | return m; 168 | } 169 | 170 | mzip_t *mzip_set_entry_point(mzip_t *m, uint32_t entry_point) { 171 | m->header->entry_point = entry_point; 172 | return m; 173 | } 174 | 175 | /** 176 | * Add a MZIP segment 177 | */ 178 | mzip_t *mzip_add_segment(mzip_t *m, uint32_t load_address, uint8_t *segment, size_t size, size_t memory_image_size) { 179 | // Update header 180 | m->header->load_address = load_address; 181 | m->header->segment_type = MZIP_SEGMENT_TYPE_UNKNOWN; 182 | m->header->segment_compressed_size = 0x0; 183 | m->header->segment_size = size; 184 | m->header->memory_image_size = memory_image_size; 185 | // Keep track of the buffer 186 | m->segment = (uint8_t *)malloc(size); 187 | memcpy(m->segment, segment, size); 188 | m->segment_buffer_size = size; 189 | 190 | uint16_t crc16 = crc16_ccitt(((uint8_t *)m->header)+0x38, sizeof(mzip_header_t)-0x38, 0x0); 191 | m->header->segment_crc16 = crc16_ccitt(m->segment, m->segment_buffer_size, crc16); 192 | 193 | return m; 194 | } 195 | 196 | /** 197 | * Compress the segment to save some space 198 | * XXX - actually you *must* compress the segment to boot it 199 | */ 200 | mzip_t *mzip_compress_segment(mzip_t *m) { 201 | int fd; 202 | size_t bytes_read; 203 | struct stat f_stat; 204 | struct zip *archive; 205 | struct zip_source *source_buffer; 206 | int error; 207 | char tmp_filename[16]; 208 | 209 | // 210 | // Create temp file 211 | // 212 | strncpy(tmp_filename, "/tmp/mzipXXXXXX", 16); 213 | fd = mkstemp(tmp_filename); 214 | 215 | // 216 | // Create archive 217 | // 218 | archive = zip_open(tmp_filename, ZIP_CREATE, &error); 219 | if (archive == NULL) { 220 | // TODO - error 221 | fprintf(stderr, "zip_open: error\n"); 222 | } 223 | 224 | if ((source_buffer = zip_source_buffer(archive, m->segment, m->segment_buffer_size, 0)) == NULL) { 225 | // TODO - error 226 | fprintf(stderr, "zip_source_buffer: error\n"); 227 | } 228 | 229 | if (zip_add(archive, "-", source_buffer) < 0) { 230 | // TODO _ error 231 | fprintf(stderr, "zip_add: error\n"); 232 | } 233 | 234 | zip_close(archive); 235 | 236 | if (stat(tmp_filename, &f_stat)) { 237 | // TODO - error 238 | fprintf(stderr, "stat: error\n"); 239 | } 240 | 241 | m->segment = (uint8_t *)malloc(f_stat.st_size); 242 | m->segment_buffer_size = f_stat.st_size; 243 | 244 | close(fd); 245 | 246 | fd = open(tmp_filename, O_RDONLY); 247 | bytes_read = read(fd, m->segment, m->segment_buffer_size); 248 | close(fd); 249 | 250 | if (bytes_read != m->segment_buffer_size) { 251 | // TODO - error 252 | fprintf(stderr, "read: did not read enough bytes (%d, should be %d)\n", bytes_read, m->segment_buffer_size); 253 | } 254 | 255 | m->header->segment_type = MZIP_SEGMENT_TYPE_PKZIP; 256 | m->header->segment_compressed_size = m->segment_buffer_size; 257 | 258 | mzip_header_host_to_bigendian(m->header); 259 | 260 | uint16_t crc16 = crc16_ccitt(((const uint8_t *)(m->header))+0x38, sizeof(mzip_header_t)-0x38, 0x0); 261 | crc16 = crc16_ccitt((const uint8_t *)(m->segment), m->segment_buffer_size, crc16); 262 | 263 | mzip_header_bigendian_to_host(m->header); 264 | 265 | m->header->segment_crc16 = crc16; 266 | 267 | return m; 268 | } 269 | 270 | /** 271 | * Save a created MZIP file on disk 272 | */ 273 | mzip_t *mzip_save(mzip_t *m, const char *filename) { 274 | int fd; 275 | ssize_t bytes_written; 276 | 277 | fd = open(filename, O_CREAT|O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 278 | if (fd < 0) { 279 | fprintf(stderr, "mzip_save: unable to open %s\n", filename); 280 | return m; 281 | } 282 | 283 | mzip_header_host_to_bigendian(m->header); 284 | 285 | m->header->header_crc16 = htobe16(crc16_ccitt((const uint8_t *)(m->header), 0x36, 0x0)); 286 | 287 | bytes_written = write(fd, (uint8_t *)m->header, sizeof(mzip_header_t)); 288 | if (bytes_written != sizeof(mzip_header_t)) { 289 | // TODO - error not enough bytes written 290 | fprintf(stderr, "mzip_save: not enough bytes written (%d, should be %d)\n", bytes_written, sizeof(mzip_header_t)); 291 | } 292 | 293 | bytes_written = write(fd, m->segment, m->segment_buffer_size); 294 | if (bytes_written != m->segment_buffer_size) { 295 | // TODO - error 296 | fprintf(stderr, "mzip_save: not enough bytes written (%d, should be %d)\n", bytes_written, m->segment_buffer_size); 297 | } 298 | 299 | close(fd); 300 | 301 | mzip_header_bigendian_to_host(m->header); 302 | 303 | return m; 304 | } 305 | 306 | /** 307 | * Destroy a created MZIP file 308 | */ 309 | void mzip_destroy(mzip_t *m) { 310 | if (m != NULL) { 311 | if (m->header != NULL) { 312 | mzip_header_free(m->header); 313 | } 314 | if (m->segment != NULL) { 315 | free(m->segment); 316 | } 317 | free(m); 318 | } 319 | } 320 | 321 | /** 322 | * Get the MZIP file segment 323 | */ 324 | uint8_t *mzip_get_segment(mzip_t *m, uint8_t *buffer, size_t size) { 325 | memcpy(buffer, m->segment, size); 326 | return buffer; 327 | } 328 | 329 | /** 330 | * Get the MZIP file header 331 | */ 332 | mzip_header_t *mzip_get_header(mzip_t *m) { 333 | return m->header; 334 | } 335 | 336 | -------------------------------------------------------------------------------- /mziptools/mzip.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012, Benjamin Vanheuverzwijn 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | /** 29 | * TODO 30 | * ~~~~ 31 | * - My guess is that a MZIP file may contains more than one segment but the 32 | * bootloader (rommon) doesn't support it. I only have one file to test the 33 | * MZIP format so it's hard to figure out. 34 | */ 35 | 36 | #ifndef __MZIP_H 37 | #define __MZIP_H 38 | 39 | #include 40 | 41 | // 42 | // MZIP object 43 | // 44 | struct mzip { 45 | int fd; 46 | const char *filename; 47 | struct mzip_header *header; 48 | uint8_t *segment; 49 | size_t segment_buffer_size; 50 | }; 51 | 52 | typedef struct mzip mzip_t; 53 | 54 | // 55 | // MZIP header 56 | // 57 | struct mzip_header { 58 | uint32_t magic; 59 | uint32_t version; 60 | uint32_t entry_point; 61 | uint32_t unknown1; // should be something like number of segments 62 | uint32_t unknown2; // ... 63 | uint32_t delimiter[8]; 64 | uint16_t segment_crc16; 65 | uint16_t header_crc16; 66 | uint32_t header_size; 67 | uint32_t load_address; 68 | uint32_t segment_type; 69 | uint32_t segment_compressed_size; 70 | uint32_t segment_size; 71 | uint32_t memory_image_size; 72 | uint32_t delimiter2[8]; 73 | }; 74 | 75 | typedef struct mzip_header mzip_header_t; 76 | 77 | // Little-endian 78 | #define MZIP_HEADER_MAGIC 0x4D5A4950 79 | #define MZIP_HEADER_VERSION_1 0x1 80 | 81 | #define MZIP_SEGMENT_TYPE_UNKNOWN 0x0 82 | #define MZIP_SEGMENT_TYPE_PKZIP 0x1 83 | 84 | // 85 | // MZIP header 86 | // 87 | mzip_header_t *mzip_header_new(); 88 | 89 | void mzip_header_free(mzip_header_t *m); 90 | 91 | 92 | // 93 | // MZIP file 94 | // 95 | 96 | // Read a mzip file 97 | mzip_t *mzip_open(const char *filename); 98 | 99 | void mzip_close(mzip_t *m); 100 | 101 | mzip_header_t *mzip_get_header(mzip_t *m); 102 | 103 | uint8_t *mzip_get_segment(mzip_t *m, uint8_t *buffer, size_t size); 104 | 105 | // Create a new mzip file 106 | mzip_t *mzip_create(void); 107 | 108 | mzip_t *mzip_set_entry_point(mzip_t *m, uint32_t entry_point); 109 | 110 | mzip_t *mzip_add_segment(mzip_t *m, uint32_t load_address, uint8_t *segment, size_t segment_size, size_t memory_image_size); 111 | 112 | mzip_t *mzip_compress_segment(mzip_t *m); 113 | 114 | mzip_t *mzip_save(mzip_t *m, const char *filename); 115 | 116 | void mzip_destroy(mzip_t *m); 117 | 118 | #endif 119 | 120 | -------------------------------------------------------------------------------- /mziptools/readmzip.c: -------------------------------------------------------------------------------- 1 | /** 2 | * readmzip - read a mzip file a-la readelf 3 | * 4 | * Copyright (c) 2012, Benjamin Vanheuverzwijn 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of the nor the 15 | * names of its contributors may be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | #include // FIXME - linux only :( 34 | #include 35 | 36 | #include "mzip.h" 37 | 38 | int usage() { 39 | printf("Usage: readmzip input_file \n"); 40 | return 0; 41 | } 42 | 43 | int main(int argc, char *argv[]) { 44 | mzip_t *mzip; 45 | mzip_header_t *header; 46 | 47 | if (argc != 2) { 48 | usage(); 49 | return EXIT_FAILURE; 50 | } 51 | 52 | mzip = mzip_open(argv[1]); 53 | 54 | header = mzip_get_header(mzip); 55 | 56 | printf("MZIP file: %s\n", basename(argv[1])); 57 | printf("--\n"); 58 | printf("Magic:\t\t\t\t0x%x (%s)\n", htobe32(header->magic), (char *)&(header->magic)); 59 | printf("Version:\t\t\t0x%x\n", htobe32(header->version)); 60 | printf("Entry point:\t\t\t0x%x\n", htobe32(header->entry_point)); 61 | printf("Unknown 1:\t\t\t0x%x\n", htobe32(header->unknown1)); 62 | printf("Unknown 2:\t\t\t0x%x\n", htobe32(header->unknown2)); 63 | printf("Segment crc16:\t\t\t0x%x\n", htobe16(header->segment_crc16)); 64 | printf("Header crc16:\t\t\t0x%x\n", htobe16(header->header_crc16)); 65 | printf("Load address:\t\t\t0x%x\n", htobe32(header->load_address)); 66 | printf("Segment type:\t\t\t0x%x (%s)\n", htobe32(header->segment_type), (htobe32(header->segment_type) == MZIP_SEGMENT_TYPE_PKZIP ? "PKZIP": "unknown")); 67 | printf("Segment compressed size:\t0x%x\n", htobe32(header->segment_compressed_size)); 68 | printf("Segment size:\t\t\t0x%x\n", htobe32(header->segment_size)); 69 | printf("Memory image size:\t\t0x%x\n", htobe32(header->memory_image_size)); 70 | 71 | mzip_close(mzip); 72 | 73 | return EXIT_SUCCESS; 74 | } 75 | --------------------------------------------------------------------------------