📄 linux.c
字号:
/* * Copyright (c) 2006 Atmark Techno, Inc. All Rights Reserved. */#include <ns9750/ioregs.h>#include <ns9750/memcpy.h>#include <target/herrno.h>#include <target/io.h>#include <target/scan.h>#include <target/str.h>#include <target/buffer.h>#include <target/memcmp.h>#include <target/setenv.h>#include <target/atag.h>#include <target/gunzip.h>#include "linux.h"#include "memmap.h"#include <target/memzero.h>#include <target/flash.h>#include "mmu.h"#include "board.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 */#define ROM_FLASH_MAJOR 31 /* major for "ROM/flash memory card" */#define FLASH0_MINOR 16 /* b 31 16 == /dev/flash0 */#define FLASH1_MINOR 17 /* b 31 17 == /dev/flash1 */#define IDE0_MAJOR 3#define IDE1_MAJOR 22static int major = RAMDISK_MAJOR;static int minor = RAMDISK0_MINOR;#define COMMAND_LINE_SIZE 1024extern unsigned long bytes_out;#define GPIO_STATUS_1_FLASHBOOT 0x10000#define SECTOR_SIZE 0x200#define INODE_SIZE 0x80#define read4_little_endian(cp) ((unsigned long)(cp[0]) + \ ((unsigned long)(cp[1]) << 8) + \ ((unsigned long)(cp[2]) << 16) + \ ((unsigned long)(cp[3]) << 24))extern int ide_detect_devices (void);extern int ide_startup_devices (void);extern int ide_read_sectors (int dev, unsigned long lba, unsigned char *buf, int count);typedef struct { unsigned char boot_ind; unsigned char head; unsigned char sector; unsigned char cyl; unsigned char sys_ind; unsigned char end_head; unsigned char end_sector; unsigned char end_cylinder; unsigned char start4[4]; unsigned char size4[4];} partition;typedef struct { unsigned long s_inodes_count; unsigned long s_blocks_count; unsigned long s_r_blocks_count; unsigned long s_free_blocks_count; unsigned long s_free_inodes_count; unsigned long s_first_data_block; unsigned long s_log_block_size; unsigned long s_log_frag_size; unsigned long s_blocks_per_group; unsigned long s_frags_per_group; unsigned long s_inodes_per_group; unsigned long s_mtime; unsigned long s_wtime; unsigned short s_mnt_count; unsigned short s_max_mnt_count; unsigned short s_magic; unsigned short s_state; unsigned short s_errors; unsigned short s_minor_rev_level; unsigned long s_lastcheck; unsigned long s_checkinterval; unsigned long s_creator_os; unsigned long s_rev_level; unsigned short s_def_resuid; unsigned short s_def_resgid; unsigned long s_first_ino; unsigned short s_inode_size; unsigned short s_block_group_nr; unsigned long s_feature_compat; unsigned long s_feature_incompat; unsigned long s_feature_ro_compat; unsigned char s_uuid[16]; char s_volume_name[16]; char s_last_mounted[64]; unsigned long s_algorithm_usage_bitmap; unsigned char s_prealloc_blocks; unsigned char s_prealloc_dir_blocks; unsigned short s_padding1; unsigned long s_reserved[204];} ext2_super_block;typedef struct { unsigned long bg_block_bitmap; unsigned long bg_inode_bitmap; unsigned long bg_inode_table; unsigned short bg_free_blocks_count; unsigned short bg_free_inodes_count; unsigned short bg_used_dirs_count; unsigned short bg_pad; unsigned long bg_reserved[3];} ext2_group_desc;typedef struct { unsigned short i_mode; unsigned short i_uid; unsigned long i_size; unsigned long i_atime; unsigned long i_ctime; unsigned long i_mtime; unsigned long i_dtime; unsigned short i_gid; unsigned short i_links_count; unsigned long i_blocks; unsigned long i_flags; union { struct { unsigned long l_i_reserved1; } linux1; struct { unsigned long h_i_translator; } hurd1; struct { unsigned long m_i_reserved1; } masix1; } osd1; unsigned long i_block[15]; unsigned long i_generation; unsigned long i_file_acl; unsigned long i_dir_acl; unsigned long i_faddr; union { struct { unsigned char l_i_frag; unsigned char l_i_fsize; unsigned short i_pad1; unsigned short l_i_uid_high; unsigned short l_i_gid_high; unsigned long l_i_reserved2; } linux2; struct { unsigned char h_i_frag; unsigned char h_i_fsize; unsigned short h_i_mode_high; unsigned short h_i_uid_high; unsigned short h_i_gid_high; unsigned long h_i_author; } hurd2; struct { unsigned char m_i_frag; unsigned char m_i_fsize; unsigned short m_pad1; unsigned long m_i_reserved2[2]; } masix2; } osd2;} ext2_inode;typedef struct { unsigned long inode; unsigned short rec_len; unsigned short name_len; char name[255];} ext2_dir_entry;static int linux_cmdfunc(int argc, char *argv[]){ 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); /* 32 MB of SDRAM at 0xc0000000 */ 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 + 3 + 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, #0x00000000\n" /* start of DRAM */ " add r4, r4, #0x00028000\n" /* kernel offset */ " mov r0, #0\n" /* kernel sanity check */ " mov r1, #256\n" /* NS9750 arch. number */ " orr r1, r1, #217\n" " mov r2, #0\n" " mov r3, #0\n" " mov pc, r4" /* go there! */ ); /* never get here */ return 0;}static int copy_file (unsigned long count, unsigned long table[], unsigned long start, unsigned long sectors_per_block, unsigned long *pfile_size, addr_t *pload_address){ int i; unsigned long file_data_sector, copy_size; unsigned char buf[SECTOR_SIZE * 8]; hprintf ("."); for (i = 0; i < count && *pfile_size > 0; i++) { file_data_sector = start + sectors_per_block * table[i]; if (ide_read_sectors (0, file_data_sector, buf, sectors_per_block)) { return -1; } copy_size = (*pfile_size > SECTOR_SIZE * sectors_per_block) ? (SECTOR_SIZE * sectors_per_block) : *pfile_size; memcpy ((unsigned char *)*pload_address, buf, copy_size); *pfile_size -= copy_size; *pload_address += copy_size; } return 0;}#if !defined (CONSOLE)char console[] = {"console=null"};#elsechar console[] = {"console=ttyAM0,115200"};#endifstatic int boot_cmdfunc(int argc, char *argv[]){ int gunzip_kernel = 1; unsigned char buf[SECTOR_SIZE * 8], buf2[SECTOR_SIZE * 8]; partition part[4]; int i, j, gzimage = 0, ext = 0; char filename[16]; unsigned long start, size, super_block_sector, sectors_per_block, blocks_per_group, inodes_per_group, group_desc_sector, first_inode_table, inode_table_sector, dir_entry_table_sector, inode, group, file_size, file_block[15], file_data_sector, addr_per_block; ext2_super_block *psb; ext2_group_desc *pgd; ext2_inode *pinode; ext2_dir_entry *pde = 0; addr_t load_address; int o_argc; if (argc > 1) { o_argc = argc; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -