📄 linux.c
字号:
/* * Copyright (c) 2007 Atmark Techno, Inc. All Rights Reserved. */#include <hermit.h>#include <target/herrno.h>#include <target/io.h>#include <target/atag.h>#include <target/gunzip.h>#include <target/memzero.h>#include <target/str.h>#include "linux.h"#include "mmu.h"#include "memregions.h"#include "board.h"#include "ide_core.h"#include <target/param.h>#include "ide_a5x0.h"/* for setting the root device */#define MINORBITS 8#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))#define RAMDISK_MAJOR 1 /* major for "RAM disk" */#define RAMDISK0_MINOR 0 /* b 1 0 == /dev/ram0 */typedef struct boot_device { char *name; u8 major; u8 minor_start; u8 minor_inc;} boot_device_t;static boot_device_t boot_device_table[] = { /* minor minor */ /* name major start inc */ {"ram", 1, 0, 1, }, {"hda", 3, 1, 1, }, {"mtdblock", 31, 0, 1, }, {"mmcblk0p", 0, 1, 1, },};#define DEFAULT_BOOT_DEVICE (1) /* RAMDISK */static int major = RAMDISK_MAJOR;static int minor = RAMDISK0_MINOR;#define COMMAND_LINE_SIZE 1024extern unsigned long bytes_out;#define MACH_ARMADILLO500 1260/**************************************************************************** * linux_cmbfunc ****************************************************************************/static int linux_cmdfunc(int argc, char *argv[]){ u32 machine_no = MACH_ARMADILLO500; struct tag *tag = (struct tag *) LINUX_PARAM_ADDRESS; /* zero param block */ memzero (tag, LINUX_PARAM_SIZE); /* set up core tag */ tag->hdr.tag = ATAG_CORE; tag->hdr.size = tag_size(tag_core); tag->u.core.flags = 0; tag->u.core.pagesize = 0x1000; tag->u.core.rootdev = MKDEV(major, minor); /* SDRAM */ tag = tag_next(tag); tag->hdr.tag = ATAG_MEM; tag->hdr.size = tag_size(tag_mem32); tag->u.mem.size = DRAM1_SIZE; tag->u.mem.start = DRAM1_START; if (major == RAMDISK_MAJOR) { /* an initial ramdisk image in flash at 0x00700000 */ tag = tag_next(tag); tag->hdr.tag = ATAG_INITRD; tag->hdr.size = tag_size(tag_initrd); tag->u.initrd.start = INITRD_START_ADDRESS; tag->u.initrd.size = bytes_out; } /* the command line arguments */ if (argc > 1) { tag = tag_next(tag); tag->hdr.tag = ATAG_CMDLINE; tag->hdr.size = (COMMAND_LINE_SIZE + 1 + 4 + sizeof(struct tag_header)) >> 2; { const unsigned char *src; unsigned char *dst; dst = tag->u.cmdline.cmdline; memzero (dst, COMMAND_LINE_SIZE); while (--argc > 0) { src = *++argv; hprintf ("Doing %s\n", src); while (*src) *dst++ = *src++; *dst++ = ' '; } *--dst = '\0'; } } tag = tag_next(tag); tag->hdr.tag = 0; tag->hdr.size = 0; /* branch to kernel image */ __asm__ volatile ( "mov r4, %0;" /* kernel start */ "mov r0, #0;" /* kernel sanity check */ "mov r1, %1;" /* machine no */ "mov r2, #0;" "mov r3, %2;" /* param */ "mov pc, r4;" /* go there! */ : : "r" (LINUX_LOAD_ADDRESS), "r" (machine_no), "r" (tag) ); /* never get here */ return 0;}/**************************************************************************** * boot_cmdfunc ****************************************************************************/static int boot_cmdfunc(int argc, char *argv[]){ int bootdevice_ide = 0; int noinitrd = 0; int c_argc = 1; char *c_argv[64]; char *param[64]; int ret; int i; led_on(); if (argc > 1) { c_argc = argc; for (i=0; i<c_argc; i++) c_argv[i] = argv[i]; } else { int param_count; param_count = get_param_count(); get_param(param, param_count); for (i=0; i<param_count; i++) { if (param[i][0] != '@') c_argv[c_argc++] = param[i]; } } for (i=1; i<c_argc; i++) { int j; if (!strcmp(c_argv[i], "noinitrd")) noinitrd = 1; else if (!strncmp(c_argv[i], "root=", 5)) { int ptr = 5; if (!strncmp(&c_argv[i][ptr], "/dev/", 5)) ptr += 5; for (j=0; j<ARRAY_SIZE(boot_device_table); j++) { char name_len = strlen(boot_device_table[j].name); if (!strncmp(&c_argv[i][ptr], boot_device_table[j].name, name_len)) { u8 dev_minor = (u8)c_argv[i][ptr + name_len] - '0'; dev_minor = minor > 10 ? 0 : minor; major = boot_device_table[j].major; minor = (boot_device_table[j].minor_start + (boot_device_table[j].minor_inc * dev_minor)); } } } }#if defined(ENABLE_IDE) { char param[] = "@bootdevice=hda*"; for (i=0; i<5; i++) { if (i == 4) { param[15] = 0x00; bootdevice_ide = 0; } else { param[15] = '1' + i; bootdevice_ide = i + 1; } ret = check_param(param); if (ret) break; bootdevice_ide = -1; } if (bootdevice_ide != -1) ret = ide_load_kernel(bootdevice_ide); else ret = -1; }#else ret = -1;#endif boost_on(BOOST_LINUX_MODE); if (ret) gunzip_object (" kernel", LINUX_SRC_ADDRESS, LINUX_LOAD_ADDRESS); if (!noinitrd) gunzip_object ("ramdisk", INITRD_SRC_ADDRESS, INITRD_LOAD_ADDRESS); boost_off (); /* load boot status */ if (check_param("@clock=532")) change_clk(CLK_532MHZ, 0); linux_cmdfunc(c_argc, c_argv); return 0;}/**************************************************************************** * commands ****************************************************************************/const command_t linux_command = { "linux", "<linux options>", "start Linux", &linux_cmdfunc };const command_t boot_command = { "boot", "", "boot default Linux kernel and ramdisk", &boot_cmdfunc };COMMAND(linux_command);COMMAND_ABBR(boot_command, 'b');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -