⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 redboot_linux_exec.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 2 页
字号:
               script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
          }
     }
     
     if (base_addr_set && !length_set) {
          diag_printf("Length required for non-standard base address\n");
          return;
     }
     
     bs_header = (struct bootsect_header *)base_addr;
     s_header = (struct setup_header *)(base_addr + SECTSIZE);
     
     if (bs_header->boot_flag != 0xAA55) {
          diag_printf("Bootsector magic not found (0x%04x @ %4p)\n", 
                      bs_header->boot_flag, &bs_header->boot_flag);
          return;
     }
     if (memcmp(s_header->magic,"HdrS",4) != 0) {
          diag_printf("Linux header (HdrS) not found\n");
          return;
     }
     if (s_header->version < SETUP_VERSION) {
          diag_printf("Linux header version = 0x%04x. "
                      "Needs to be at least 0x%04x\n",
                      s_header->version, SETUP_VERSION);
          return;
     }
     
     setup_sects = bs_header->setup_sects ? bs_header->setup_sects : 4;
     
     entry = s_header->code32_start;
     // + 1 for boot sector
     base_addr += (setup_sects + 1 ) * SECTSIZE;
     length -= (setup_sects + 1 ) * SECTSIZE;
     
     mem_size = (cyg_uint32)HAL_MEM_REAL_REGION_TOP((cyg_uint8 *)0x1000000);
     mem_size >>= 10;   // convert from bytes to kilobytes.
     // Result of int15 ax=0xe801
     int15_e801 = mem_size - 1024 ; // 1M+ only
     
     // Stop all network devices
#ifdef CYGPKG_IO_ETH_DRIVERS
     eth_drv_stop();
#endif
     
#ifdef CYGPKG_IO_PCI
     cyg_pci_init();
#endif
     
#if CYGINT_HAL_I386_PCMB_SCREEN_SUPPORT > 0
     cyg_hal_plf_screen_position(&xpos, &ypos);
#endif
     
     HAL_DISABLE_INTERRUPTS(oldints);
     HAL_DCACHE_SYNC();
     HAL_ICACHE_DISABLE();
     HAL_DCACHE_DISABLE();
     HAL_DCACHE_SYNC();
     HAL_ICACHE_INVALIDATE_ALL();
     HAL_DCACHE_INVALIDATE_ALL();
     
     // Clear the data area
     memset ( (void*)PARAM, 0, 512 );
     
     if ( cmd_line_set )
          strcpy( PARAM_CMDLINE, cmd_line );
     else
          strcpy( PARAM_CMDLINE, "auto");
     
     memcpy((void*)(PARAM+SECTSIZE), s_header, sizeof(struct setup_header));
     s_header = (struct setup_header*)(0x90000+SECTSIZE);
     
     s_header->version = SETUP_VERSION;
     
     // Command Line
     s_header->cmd_line_ptr = 0x93400;
     
     // Loader type
     s_header->type_of_loader = 0xFF;
     
     // Fill in the interesting bits of data area...
     // ... Memory sizes
     PARAM_EXT_MEM_K = int15_e801;
     PARAM_ALT_MEM_K = int15_e801;
     
     // ... No e820 map!
     PARAM_E820NR = 0;   // Length of map
     
     // ... Video stuff
     PARAM_ORIG_X = xpos;
     PARAM_ORIG_Y = ypos;
     PARAM_ORIG_VIDEO_MODE = 2;
     PARAM_ORIG_VIDEO_COLS = 80;
     PARAM_ORIG_VIDEO_LINES = 25;
     PARAM_ORIG_VIDEO_ISVGA = 0;
     
     // Copy trampoline to trampoline address
     memcpy((char *)CYGHWR_REDBOOT_I386_TRAMPOLINE_ADDRESS,
            __tramp_start__,
            __tramp_end__ - __tramp_start__);
     
     trampoline(base_addr, length, entry);
     
#define _QUOTE_STRING(__x__)    #__x__
#define QUOTE_STRING(__x__)     _QUOTE_STRING(__x__)
     
     asm volatile (
          "__tramp_start__:\n"
          "       push   %%ebp;\n"
          "       mov    %%esp,%%ebp;\n"
          
          /* STACK IS:
           * OLD BP               0x4(%ebp)
           * ENTRY                0x8(%ebp)
           * LENGTH               0xC(%ebp)
           * BASE ADDRESS         0x10(%ebp) */
          
          "       movl    0x10(%%ebp), %%ebx;\n"  /* Save entry point
                                                     in EBX, because
                                                     we overwrite the
                                                     stack */
          
          "       cli;\n"                         /* no interrupts allowed ! */
          
          "       movb    $0x80, %%al;\n"         /* disable NMI for bootup */
          "       outb    %%al, $0x70;\n"         /* sequence */
          
          /* Copy GDT to RAM at 0x90400 */
          "       movl    $(linux_gdt_end - linux_gdt), %%ecx;\n" /* Length */
          "       shrl    $2, %%ecx;\n"                   /* Bytes -> Longs */
          "       leal    linux_gdt, %%eax;\n"            /* Source */
          "       movl    %%eax, %%esi;\n"
          "       movl    $(0x90400), %%edi;\n"           /* Dest */
          "1:\n"
          "       lodsl;\n"
          "       stosl;\n"
          "       loop    1b;\n"
          
          /* If necessary, copy linux image to correct location */
          "       movl    0x8(%%ebp), %%esi;\n"           /* Source */
          "       movl    %%ebx, %%edi;\n"                /* Destination
                                                           * (saved in
                                                           * EBX
                                                           * above) */
          "       cmpl    %%edi, %%esi;\n"
          "       je      2f;\n"
          "       movl    0xC(%%ebp), %%ecx;\n"           /* Length */
          "       shrl    $2, %%ecx;\n"                   /* Bytes to Longs */
          "1:\n"
          "       lodsl;\n"
          "       stosl;\n"
          "       loop    1b;\n"
          "2:\n"
          
          /* Create a GDT descriptor at 0 and load it */
          "       movl    $0x90000, %%esi;\n"
          "       movw    $(linux_gdt_end - linux_gdt), %%ax;\n"
          "       dec     %%ax;\n"
          "       movw    %%ax,0;\n"
          "       movl    $0x90400,%%eax;\n"
          "       movl    %%eax,2;\n"
          "       lgdt    0;\n"
          
          /* Reload segment registers */
          "       mov     $(0x18), %%eax;\n"
          "       movl    %%eax, %%ds;\n"
          "       movl    %%eax, %%es;\n"
          "       movl    %%eax, %%fs;\n"
          "       movl    %%eax, %%gs;\n"
          
          /* Reload CS */
          "       ljmp    $(0x10), $(1f - __tramp_start__ + " 
          QUOTE_STRING(CYGHWR_REDBOOT_I386_TRAMPOLINE_ADDRESS) ");\n"
          "1:\n"
          
          /* Start kernel */
          "       jmp     *%%ebx;\n"
          
          ".ALIGN 4, 0xCC;\n"
          
          "__tramp_end__:\n"
          
          /* Descriptor tables */
          "linux_gdt:\n"
          "       .word   0, 0, 0, 0;\n"    /* dummy */
          "       .word   0, 0, 0, 0;\n"    /* unused */
          "       .word   0xFFFF;\n"        /* 4Gb - (0x100000*0x1000
                                               * = * 4Gb) */
          "       .word   0;\n"             /* base address = 0 */
          "       .word   0x9A00;\n"        /* code read/exec */
          "       .word   0x00CF;\n"        /* granularity = 4096, 386 */
          /*  (+5th nibble of limit) */
          "       .word   0xFFFF;\n"        /* 4Gb - (0x100000*0x1000 = 4Gb) */
          "       .word   0;\n"             /* base address = 0 */
          "       .word   0x9200;\n"        /* data read/write */
          "       .word   0x00CF;\n"        /* granularity = 4096, 386 */
                                            /*  (+5th nibble of limit) */
          "linux_gdt_end:\n"
          : : : "eax", "ebx", "ecx");
}

RedBoot_cmd("exec",
            "Execute a Linux image",
            "[-w timeout] [-b <base address> [-l <image length>]]\n"
            "        [-r <ramdisk addr> [-s <ramdisk length>]]\n"
            "        [-c \"kernel command line\"]",
            do_exec
     );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -