📄 redboot_linux_exec.c
字号:
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 + -