world.c
/* * "Small Hello World" example. * * This example prints 'Hello from Nios II' to the STDOUT stream. It runs on * the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example * designs. It requires a STDOUT device in your system's hardware. * * The purpose of this example is to demonstrate the smallest possible Hello * World application, using the Nios II HAL library. The memory footprint * of this hosted application is ~332 bytes by default using the standard * reference design. For a more fully featured Hello World application * example, see the example titled "Hello World". * * The memory footprint of this example has been reduced by making the * following changes to the normal "Hello World" example. * Check in the Nios II Software Developers Manual for a more complete * description. * * In the SW Application project (small_hello_world): * * - In the C/C++ Build page * * - Set the Optimization Level to -Os * * In System Library project (small_hello_world_syslib): * - In the C/C++ Build page * * - Set the Optimization Level to -Os * * - Define the preprocessor option ALT_NO_INSTRUCTION_EMULATION * This removes software exception handling, which means that you cannot * run code compiled for Nios II cpu with a hardware multiplier on a core * without a the multiply unit. Check the Nios II Software Developers * Manual for more details. * * - In the System Library page: * - Set Periodic system timer and Timestamp timer to none * This prevents the automatic inclusion of the timer driver. * * - Set Max file descriptors to 4 * This reduces the size of the file handle pool. * * - Check Main function does not exit * - Uncheck Clean exit (flush buffers) * This removes the unneeded call to exit when main returns, since it * won't. * * - Check Don't use C++ * This builds without the C++ support code. * * - Check Small C library * This uses a reduced functionality C library, which lacks * support for buffering, file IO, floating point and getch(), etc. * Check the Nios II Software Developers Manual for a complete list. * * - Check Reduced device drivers * This uses reduced functionality drivers if they're available. For the * standard design this means you get polled UART and JTAG UART drivers, * no support for the LCD driver and you lose the ability to program * CFI compliant flash devices. * * - Check Access device drivers directly * This bypasses the device file system to access device drivers directly. * This eliminates the space required for the device file system services. * It also provides a HAL version of libc services that access the drivers * directly, further reducing space. Only a limited number of libc * functions are available in this configuration. * * - Use ALT versions of stdio routines: * * Function Description * =============== ===================================== * alt_printf Only supports %s, %x, and %c ( < 1 Kbyte) * alt_putstr Smaller overhead than puts with direct drivers * Note this function doesn't add a newline. * alt_putchar Smaller overhead than putchar with direct drivers * alt_getchar Smaller overhead than getchar with direct drivers * */ #include "sys/alt_stdio.h" int main() { alt_putstr("Hello from Nios II!\n"); /* Event loop never exits. */ while (1); return 0; }
#!/bin/sh inp="hello_world_small_0" oup="world" nios2-elf-size ${inp}.elf > ${oup}.size.txt nios2-elf-objdump -dS ${inp}.elf >${oup}.disassemble.txt nios2-elf-objdump -h ${inp}.elf > ${oup}.headers.txt nios2-elf-objcopy -S -O binary ${inp}.elf ${oup}.bin nios2-elf-nm ${inp}.elf > ${oup}.symbols.txt od -Ax -j0x274 -txz ${oup}.bin > ${oup}.od.txt
text data bss dec hex filename 652 16 0 668 29c hello_world_small_0.elf
hello_world_small_0.elf: file format elf32-littlenios2 Sections: Idx Name Size VMA LMA File off Algn 0 .entry 00000020 00008000 00008000 00000074 2**5 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .exceptions 00000000 00008020 00008020 00000310 2**0 CONTENTS 2 .text 00000254 00008020 00008020 00000094 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 .rodata 00000018 00008274 00008274 000002e8 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .rwdata 00000010 0000828c 0000828c 00000300 2**2 CONTENTS, ALLOC, LOAD, DATA, SMALL_DATA 5 .bss 00000000 0000829c 0000829c 00000310 2**0 ALLOC 6 .onchip_mem 00000000 0000829c 0000829c 00000310 2**0 CONTENTS 7 .comment 000001b8 00000000 00000000 00000310 2**0 CONTENTS, READONLY 8 .debug_aranges 00000168 00000000 00000000 000004c8 2**3 CONTENTS, READONLY, DEBUGGING 9 .debug_pubnames 000001a0 00000000 00000000 00000630 2**0 CONTENTS, READONLY, DEBUGGING 10 .debug_info 000009cc 00000000 00000000 000007d0 2**0 CONTENTS, READONLY, DEBUGGING 11 .debug_abbrev 00000556 00000000 00000000 0000119c 2**0 CONTENTS, READONLY, DEBUGGING 12 .debug_line 0000194c 00000000 00000000 000016f2 2**0 CONTENTS, READONLY, DEBUGGING 13 .debug_frame 00000160 00000000 00000000 00003040 2**2 CONTENTS, READONLY, DEBUGGING 14 .debug_str 00000640 00000000 00000000 000031a0 2**0 CONTENTS, READONLY, DEBUGGING 15 .debug_alt_sim_info 00000030 00000000 00000000 000037e0 2**2 CONTENTS, READONLY, DEBUGGING
hello_world_small_0.elf: file format elf32-littlenios2 Disassembly of section .entry: 00008000 <__reset>: /* Assume the instruction cache size is always a power of two. */ #if NIOS2_ICACHE_SIZE > 0x8000 movhi r2, %hi(NIOS2_ICACHE_SIZE) #else movui r2, NIOS2_ICACHE_SIZE 8000: 00840014 movui r2,4096 #endif 0: initi r2 8004: 1001483a initi r2 addi r2, r2, -NIOS2_ICACHE_LINE_SIZE 8008: 10bff804 addi r2,r2,-32 bgt r2, zero, 0b 800c: 00bffd16 blt zero,r2,8004 <__alt_mem_onchip_mem+0x4> 1: /* * The following debug information tells the ISS not to run the loop above * but to perform its actions using faster internal code. */ .pushsection .debug_alt_sim_info .int 1, 1, 0b, 1b .popsection #endif /* Initialize Instruction Cache */ /* * Jump to the _start entry point in the .text section if reset code * is allowed or if optimizing for RTL simulation. */ #if defined(ALT_ALLOW_CODE_AT_RESET) || defined(ALT_SIM_OPTIMIZE) /* Jump to the _start entry point in the .text section. */ movhi r1, %hi(_start) 8010: 00400034 movhi at,0 ori r1, r1, %lo(_start) 8014: 08600814 ori at,at,32800 jmp r1 8018: 0800683a jmp at 0000801c <_exit>: 801c: 00000000 call 0 <__alt_mem_onchip_mem-0x8000> Disassembly of section .text: 00008020 <_start>: .size __reset, . - __reset #endif /* Jump to _start */ /* * When not using exit, provide an _exit symbol to prevent unresolved * references to _exit from the linker script. */ #ifdef ALT_NO_EXIT .globl _exit _exit: #endif /*************************************************************************\ | TEXT SECTION (.text) | \*************************************************************************/ /* * Start of the .text section, and also the code entry point when * the code is executed by a bootloader rather than directly from reset. */ .section .text .align 2 .globl _start .type _start, @function _start: /* * Initialize the data cache if present (i.e. size > 0) and not * optimizing for RTL simulation. * RTL simulations can ensure the data cache is already initialized * so skipping this loop speeds up RTL simulation. */ #if NIOS2_DCACHE_SIZE > 0 && !defined(ALT_SIM_OPTIMIZE) /* Assume the data cache size is always a power of two. */ #if NIOS2_DCACHE_SIZE > 0x8000 movhi r2, %hi(NIOS2_DCACHE_SIZE) #else movui r2, NIOS2_DCACHE_SIZE 8020: 00820014 movui r2,2048 #endif 0: initd 0(r2) 8024: 10000033 initd 0(r2) addi r2, r2, -NIOS2_DCACHE_LINE_SIZE 8028: 10bff804 addi r2,r2,-32 bgt r2, zero, 0b 802c: 00bffd16 blt zero,r2,8024 <__ram_exceptions_end+0x4> 1: /* * The following debug information tells the ISS not to run the loop above * but to perform its actions using faster internal code. */ .pushsection .debug_alt_sim_info .int 2, 1, 0b, 1b .popsection #endif /* Initialize Data Cache */ /* Log that caches have been initialized. */ ALT_LOG_PUTS(alt_log_msg_cache) /* Log that the stack pointer is about to be setup. */ ALT_LOG_PUTS(alt_log_msg_stackpointer) /* * Now that the caches are initialized, set up the stack pointer. * The value provided by the linker is assumed to be correctly aligned. */ movhi sp, %hi(__alt_stack_pointer) 8030: 06c00074 movhi sp,1 ori sp, sp, %lo(__alt_stack_pointer) 8034: dec00014 ori sp,sp,0 /* Set up the global pointer. */ movhi gp, %hi(_gp) 8038: 06800074 movhi gp,1 ori gp, gp, %lo(_gp) 803c: d680a314 ori gp,gp,652 /* * Clear the BSS if not optimizing for RTL simulation. * * This uses the symbols: __bss_start and __bss_end, which are defined * by the linker script. They mark the begining and the end of the bss * region. The linker script guarantees that these values are word aligned. */ #ifndef ALT_SIM_OPTIMIZE /* Log that the BSS is about to be cleared. */ ALT_LOG_PUTS(alt_log_msg_bss) movhi r2, %hi(__bss_start) 8040: 00800034 movhi r2,0 ori r2, r2, %lo(__bss_start) 8044: 10a0a714 ori r2,r2,33436 movhi r3, %hi(__bss_end) 8048: 00c00034 movhi r3,0 ori r3, r3, %lo(__bss_end) 804c: 18e0a714 ori r3,r3,33436 beq r2, r3, 1f 8050: 10c00326 beq r2,r3,8060 <__ram_exceptions_end+0x40> 0: stw zero, (r2) 8054: 10000015 stw zero,0(r2) addi r2, r2, 4 8058: 10800104 addi r2,r2,4 bltu r2, r3, 0b 805c: 10fffd36 bltu r2,r3,8054 <__ram_exceptions_end+0x34> 1: /* * The following debug information tells the ISS not to run the loop above * but to perform its actions using faster internal code. */ .pushsection .debug_alt_sim_info .int 3, 1, 0b, 1b .popsection #endif /* ALT_SIM_OPTIMIZE */ /* * The alt_load() facility is normally used when there is no bootloader. * It copies some sections into RAM so it acts like a mini-bootloader. */ #ifdef CALL_ALT_LOAD #ifdef ALT_STACK_CHECK /* * If the user has selected stack checking then we need to set up a safe * value in the stack limit register so that the relocation functions * don't think the stack has overflowed (the contents of the rwdata * section aren't defined until alt_load() has been called). */ mov et, zero #endif call alt_load 8060: 00080840 call 8084 <alt_load> #endif /* CALL_ALT_LOAD */ #ifdef ALT_STACK_CHECK /* * Set up the stack limit (if required). The linker has set up the * copy of the variable which is in memory. */ ldw et, %gprel(alt_stack_limit_value)(gp) #endif /* Log that alt_main is about to be called. */ ALT_LOG_PUTS(alt_log_msg_alt_main) /* Call the C entry point. It should never return. */ call alt_main 8064: 00081400 call 8140 <alt_main> 00008068 <alt_after_alt_main>: /* Wait in infinite loop in case alt_main does return. */ alt_after_alt_main: br alt_after_alt_main 8068: 003fff06 br 8068 <alt_after_alt_main> 0000806c <main>: #include "sys/alt_stdio.h" int main() { 806c: deffff04 addi sp,sp,-4 alt_putstr("Hello from Nios II!\n"); 8070: 01000074 movhi r4,1 8074: 21209d04 addi r4,r4,-32140 8078: dfc00015 stw ra,0(sp) 807c: 00081780 call 8178 <alt_putstr> 8080: 003fff06 br 8080 <main+0x14> 00008084 <alt_load>: * RAM any sections that are required. */ void alt_load (void) { 8084: deffff04 addi sp,sp,-4 static void ALT_INLINE alt_load_section (alt_u32* from, alt_u32* to, alt_u32* end) { 8088: 01000074 movhi r4,1 808c: 2120a304 addi r4,r4,-32116 8090: 00c00074 movhi r3,1 8094: 18e0a304 addi r3,r3,-32116 8098: dfc00015 stw ra,0(sp) static void ALT_INLINE alt_load_section (alt_u32* from, alt_u32* to, alt_u32* end) { 809c: 01400074 movhi r5,1 80a0: 2960a704 addi r5,r5,-32100 if (to != from) 80a4: 19000626 beq r3,r4,80c0 <alt_load+0x3c> { while( to != end ) { *to++ = *from++; 80a8: 19400526 beq r3,r5,80c0 <alt_load+0x3c> 80ac: 20800017 ldw r2,0(r4) 80b0: 21000104 addi r4,r4,4 80b4: 18800015 stw r2,0(r3) 80b8: 18c00104 addi r3,r3,4 80bc: 197ffb1e bne r3,r5,80ac <alt_load+0x28> 80c0: 01000074 movhi r4,1 80c4: 21200804 addi r4,r4,-32736 80c8: 00c00074 movhi r3,1 80cc: 18e00804 addi r3,r3,-32736 80d0: 01400074 movhi r5,1 80d4: 29600804 addi r5,r5,-32736 80d8: 19000626 beq r3,r4,80f4 <alt_load+0x70> 80dc: 19400526 beq r3,r5,80f4 <alt_load+0x70> 80e0: 20800017 ldw r2,0(r4) 80e4: 21000104 addi r4,r4,4 80e8: 18800015 stw r2,0(r3) 80ec: 18c00104 addi r3,r3,4 80f0: 197ffb1e bne r3,r5,80e0 <alt_load+0x5c> 80f4: 01000074 movhi r4,1 80f8: 21209d04 addi r4,r4,-32140 80fc: 00c00074 movhi r3,1 8100: 18e09d04 addi r3,r3,-32140 8104: 01400074 movhi r5,1 8108: 2960a304 addi r5,r5,-32116 810c: 19000626 beq r3,r4,8128 <alt_load+0xa4> 8110: 19400526 beq r3,r5,8128 <alt_load+0xa4> 8114: 20800017 ldw r2,0(r4) 8118: 21000104 addi r4,r4,4 811c: 18800015 stw r2,0(r3) 8120: 18c00104 addi r3,r3,4 8124: 197ffb1e bne r3,r5,8114 <alt_load+0x90> /* * Copy the .rwdata section. */ alt_load_section (&__flash_rwdata_start, &__ram_rwdata_start, &__ram_rwdata_end); /* * Copy the exception handler. */ alt_load_section (&__flash_exceptions_start, &__ram_exceptions_start, &__ram_exceptions_end); /* * Copy the .rodata section. */ alt_load_section (&__flash_rodata_start, &__ram_rodata_start, &__ram_rodata_end); /* * Now ensure that the caches are in synch. */ alt_dcache_flush_all(); 8128: 00081f00 call 81f0 <alt_dcache_flush_all> alt_icache_flush_all(); 812c: 02000074 movhi r8,1 8130: 42208204 addi r8,r8,-32248 8134: dfc00017 ldw ra,0(sp) 8138: dec00104 addi sp,sp,4 813c: 4000683a jmp r8 00008140 <alt_main>: * the users application, i.e. main(). */ void alt_main (void) { 8140: deffff04 addi sp,sp,-4 8144: dfc00015 stw ra,0(sp) static ALT_INLINE void ALT_ALWAYS_INLINE alt_irq_init (const void* base) { NIOS2_WRITE_IENABLE (0); 8148: 000170fa wrctl ienable,zero NIOS2_WRITE_STATUS (NIOS2_STATUS_PIE_MSK); 814c: 00800044 movi r2,1 8150: 1001703a wrctl status,r2 /* ALT LOG - please see HAL/sys/alt_log_printf.h for details */ ALT_LOG_PRINT_BOOT("[alt_main.c] Entering alt_main, calling alt_irq_init.\r\n"); /* Initialize the interrupt controller. */ alt_irq_init (ALT_IRQ_BASE); /* Initialize the operating system */ ALT_LOG_PRINT_BOOT("[alt_main.c] Done alt_irq_init, calling alt_os_init.\r\n"); ALT_OS_INIT(); /* * Initialize the semaphore used to control access to the file descriptor * list. */ ALT_LOG_PRINT_BOOT("[alt_main.c] Done OS Init, calling alt_sem_create.\r\n"); ALT_SEM_CREATE (&alt_fd_list_lock, 1); /* Initialize the device drivers/software components. */ ALT_LOG_PRINT_BOOT("[alt_main.c] Calling alt_sys_init.\r\n"); alt_sys_init(); 8154: 00081b80 call 81b8 <alt_sys_init> ALT_LOG_PRINT_BOOT("[alt_main.c] Done alt_sys_init.\r\n"); #if !defined(ALT_USE_DIRECT_DRIVERS) && (defined(ALT_STDIN_PRESENT) || defined(ALT_STDOUT_PRESENT) || defined(ALT_STDERR_PRESENT)) /* * Redirect stdio to the apropriate devices now that the devices have * been initialized. This is only done if the user has requested these * devices be present (not equal to /dev/null) and if direct drivers * aren't being used. */ ALT_LOG_PRINT_BOOT("[alt_main.c] Redirecting IO.\r\n"); alt_io_redirect(ALT_STDOUT, ALT_STDIN, ALT_STDERR); #endif #ifndef ALT_NO_C_PLUS_PLUS /* * Call the C++ constructors */ ALT_LOG_PRINT_BOOT("[alt_main.c] Calling C++ constructors.\r\n"); _do_ctors (); #endif /* ALT_NO_C_PLUS_PLUS */ #if !defined(ALT_NO_C_PLUS_PLUS) && !defined(ALT_NO_CLEAN_EXIT) && !defined(ALT_NO_EXIT) /* * Set the C++ destructors to be called at system shutdown. This is only done * if a clean exit has been requested (i.e. the exit() function has not been * redefined as _exit()). This is in the interest of reducing code footprint, * in that the atexit() overhead is removed when it's not needed. */ ALT_LOG_PRINT_BOOT("[alt_main.c] Calling atexit.\r\n"); atexit (_do_dtors); #endif /* * Finally, call main(). The return code is then passed to a subsequent * call to exit() unless the application is never supposed to exit. */ ALT_LOG_PRINT_BOOT("[alt_main.c] Calling main.\r\n"); #ifdef ALT_NO_EXIT main (alt_argc, alt_argv, alt_envp); 8158: d1200217 ldw r4,-32760(gp) 815c: d1600117 ldw r5,-32764(gp) 8160: d1a00017 ldw r6,-32768(gp) 8164: 02000074 movhi r8,1 8168: 42201b04 addi r8,r8,-32660 816c: dfc00017 ldw ra,0(sp) 8170: dec00104 addi sp,sp,4 8174: 4000683a jmp r8 00008178 <alt_putstr>: * Otherwise, uses newlib provided fputs() routine. */ int alt_putstr(const char* str) { 8178: defffe04 addi sp,sp,-8 817c: dc400015 stw r17,0(sp) 8180: dfc00115 stw ra,4(sp) 8184: 2023883a mov r17,r4 #ifdef ALT_USE_DIRECT_DRIVERS ALT_DRIVER_WRITE_EXTERNS(ALT_STDOUT_DEV); return ALT_DRIVER_WRITE(ALT_STDOUT_DEV, str, strlen(str), 0); 8188: 00082540 call 8254 <strlen> 818c: 880b883a mov r5,r17 8190: 100d883a mov r6,r2 8194: 01000074 movhi r4,1 8198: 2120a604 addi r4,r4,-32104 819c: 000f883a mov r7,zero 81a0: 02000074 movhi r8,1 81a4: 42206f04 addi r8,r8,-32324 #else return fputs(str, stdout); #endif } 81a8: dfc00117 ldw ra,4(sp) 81ac: dc400017 ldw r17,0(sp) 81b0: dec00204 addi sp,sp,8 81b4: 4000683a jmp r8 000081b8 <alt_sys_init>: 81b8: f800283a ret 000081bc <altera_avalon_jtag_uart_write>: const char * ptr, int count, int flags) { unsigned int base = sp->base; const char * end = ptr + count; 81bc: 298f883a add r7,r5,r6 81c0: 21000017 ldw r4,0(r4) while (ptr < end) if ((IORD_ALTERA_AVALON_JTAG_UART_CONTROL(base) & ALTERA_AVALON_JTAG_UART_CONTROL_WSPACE_MSK) != 0) IOWR_ALTERA_AVALON_JTAG_UART_DATA(base, *ptr++); 81c4: 29c0082e bgeu r5,r7,81e8 <altera_avalon_jtag_uart_write+0x2c> 81c8: 20c00104 addi r3,r4,4 81cc: 18800037 ldwio r2,0(r3) 81d0: 10bfffec andhi r2,r2,65535 81d4: 10000326 beq r2,zero,81e4 <altera_avalon_jtag_uart_write+0x28> 81d8: 28800007 ldb r2,0(r5) 81dc: 20800035 stwio r2,0(r4) 81e0: 29400044 addi r5,r5,1 81e4: 29fff936 bltu r5,r7,81cc <altera_avalon_jtag_uart_write+0x10> return count; } 81e8: 3005883a mov r2,r6 81ec: f800283a ret 000081f0 <alt_dcache_flush_all>: { #if NIOS2_DCACHE_SIZE > 0 char* i; for (i = (char*) 0; i < (char*) NIOS2_DCACHE_SIZE; i+= NIOS2_DCACHE_LINE_SIZE) 81f0: 0005883a mov r2,zero 81f4: 00c1ffc4 movi r3,2047 { __asm__ volatile ("flushd (%0)" :: "r" (i)); 81f8: 1000003b flushd 0(r2) 81fc: 10800804 addi r2,r2,32 8200: 18bffd2e bgeu r3,r2,81f8 <alt_dcache_flush_all+0x8> 8204: f800283a ret 00008208 <alt_icache_flush_all>: void alt_icache_flush_all (void) { #if NIOS2_ICACHE_SIZE > 0 alt_icache_flush (0, NIOS2_ICACHE_SIZE); 8208: 0009883a mov r4,zero 820c: 01440004 movi r5,4096 8210: 02000074 movhi r8,1 8214: 42208704 addi r8,r8,-32228 8218: 4000683a jmp r8 0000821c <alt_icache_flush>: /* * This is the most we would ever need to flush. */ if (len > NIOS2_ICACHE_SIZE) 821c: 00840004 movi r2,4096 8220: 1140012e bgeu r2,r5,8228 <alt_icache_flush+0xc> { len = NIOS2_ICACHE_SIZE; 8224: 100b883a mov r5,r2 } end = ((char*) start) + len; 8228: 214b883a add r5,r4,r5 for (i = start; i < end; i+= NIOS2_ICACHE_LINE_SIZE) 822c: 2007883a mov r3,r4 8230: 1940032e bgeu r3,r5,8240 <alt_icache_flush+0x24> { __asm__ volatile ("flushi %0" :: "r" (i)); 8234: 1800603a flushi r3 8238: 18c00804 addi r3,r3,32 823c: 197ffd36 bltu r3,r5,8234 <alt_icache_flush+0x18> } /* * For an unaligned flush request, we've got one more line left. * Note that this is dependent on NIOS2_ICACHE_LINE_SIZE to be a * multiple of 2 (which it always is). */ if (((alt_u32) start) & (NIOS2_ICACHE_LINE_SIZE - 1)) 8240: 208007cc andi r2,r4,31 8244: 10000126 beq r2,zero,824c <alt_icache_flush+0x30> { __asm__ volatile ("flushi %0" :: "r" (i)); 8248: 1800603a flushi r3 } /* * Having flushed the cache, flush any stale instructions in the * pipeline */ __asm__ volatile ("flushp"); 824c: 0000203a flushp 8250: f800283a ret 00008254 <strlen>: 8254: 20800007 ldb r2,0(r4) 8258: 2007883a mov r3,r4 825c: 10000326 beq r2,zero,826c <strlen+0x18> 8260: 21000044 addi r4,r4,1 8264: 20800007 ldb r2,0(r4) 8268: 103ffd1e bne r2,zero,8260 <strlen+0xc> 826c: 20c5c83a sub r2,r4,r3 8270: f800283a ret
000274 6c6c6548 7266206f 4e206d6f 20736f69 >Hello from Nios < 000284 0a214949 00000000 00000000 00000000 >II!.............< 000294 00000000 00011030 >....0...< 00029c
Maintained by John Loomis, last updated Wed Jan 16 22:16:42 2008