khypervisor
v1
|
00001 #include "loadlinux.h" 00002 #include <log/string.h> 00003 #include <log/print.h> 00004 00005 /* list of possible tags */ 00006 #define ATAG_NONE 0x00000000 00007 #define ATAG_CORE 0x54410001 00008 #define ATAG_MEM 0x54410002 00009 #define ATAG_VIDEOTEXT 0x54410003 00010 #define ATAG_RAMDISK 0x54410004 00011 #define ATAG_INITRD2 0x54420005 00012 #define ATAG_SERIAL 0x54410006 00013 #define ATAG_REVISION 0x54410007 00014 #define ATAG_VIDEOLFB 0x54410008 00015 #define ATAG_CMDLINE 0x54410009 00016 00017 #define tag_next(t) ((struct atag *)((uint32_t *)(t) + (t)->hdr.size)) 00018 #define tag_size(type) ((sizeof(struct atag_header) + sizeof(struct type)) >> 2) 00019 00020 /* structures for each atag */ 00021 00022 struct atag_header { 00023 uint32_t size; /* length of tag in words including this header */ 00024 uint32_t tag; /* tag type */ 00025 }; 00026 struct atag_core { 00027 uint32_t flags; 00028 uint32_t pagesize; 00029 uint32_t rootdev; 00030 }; 00031 00032 struct atag_mem { 00033 uint32_t size; 00034 uint32_t start; 00035 }; 00036 struct atag_serialnr { 00037 uint32_t low; 00038 uint32_t high; 00039 }; 00040 00041 struct atag_revision { 00042 uint32_t rev; 00043 }; 00044 struct atag_cmdline { 00045 char cmdline[1]; 00046 }; 00047 struct atag_ramdisk { 00048 uint32_t flags; /* bit 0 = load, bit 1 = prompt */ 00049 uint32_t size; /* decompressed ramdisk size in _kilo_ bytes */ 00050 uint32_t start; /* starting block of floppy-based RAM disk image */ 00051 }; 00052 struct atag_videotext { 00053 uint8_t x; /* width of display */ 00054 uint8_t y; /* height of display */ 00055 uint16_t video_page; 00056 uint8_t video_mode; 00057 uint8_t video_cols; 00058 uint16_t video_ega_bx; 00059 uint8_t video_lines; 00060 uint8_t video_isvga; 00061 uint16_t video_points; 00062 }; 00063 struct atag_initrd2 { 00064 uint32_t start; /* physical start address */ 00065 uint32_t size; /* size of compressed ramdisk image in bytes */ 00066 }; 00067 struct atag_videolfb { 00068 uint16_t lfb_width; 00069 uint16_t lfb_height; 00070 uint16_t lfb_depth; 00071 uint16_t lfb_linelength; 00072 uint32_t lfb_base; 00073 uint32_t lfb_size; 00074 uint8_t red_size; 00075 uint8_t red_pos; 00076 uint8_t green_size; 00077 uint8_t green_pos; 00078 uint8_t blue_size; 00079 uint8_t blue_pos; 00080 uint8_t rsvd_size; 00081 uint8_t rsvd_pos; 00082 }; 00083 struct atag { 00084 struct atag_header hdr; 00085 union { 00086 struct atag_core core; 00087 struct atag_mem mem; 00088 struct atag_videotext videotext; 00089 struct atag_ramdisk ramdisk; 00090 struct atag_initrd2 initrd2; 00091 struct atag_serialnr serialnr; 00092 struct atag_revision revision; 00093 struct atag_videolfb videolfb; 00094 struct atag_cmdline cmdline; 00095 } u; 00096 }; 00097 00098 static struct atag *_params; /* used to point at the current tag */ 00099 00100 static void setup_core_tag( void * address, long pagesize ) 00101 { 00102 _params = (struct atag *)address; /* Initialise parameters to start at given address */ 00103 00104 _params->hdr.tag = ATAG_CORE; /* start with the core tag */ 00105 _params->hdr.size = tag_size(atag_core); /* size the tag */ 00106 _params->u.core.flags = 1; /* ensure read-only */ 00107 _params->u.core.pagesize = pagesize; /* systems pagesize (4k) */ 00108 _params->u.core.rootdev = 0; /* zero root device (typicaly overidden from commandline )*/ 00109 00110 _params = tag_next(_params); /* move pointer to next tag */ 00111 } 00112 00113 static void setup_revision_tag( void ) 00114 { 00115 _params->hdr.tag = ATAG_REVISION; 00116 _params->hdr.size = tag_size (atag_revision); 00117 _params->u.revision.rev = 0xcfdfdfdf; 00118 _params = tag_next (_params); 00119 } 00120 00121 static void setup_cmdline_tag( const char * line ) 00122 { 00123 int linelen = strlen(line); 00124 00125 if(!linelen) 00126 return; /* do not insert a tag for an empty commandline */ 00127 00128 _params->hdr.tag = ATAG_CMDLINE; /* Commandline tag */ 00129 _params->hdr.size = (sizeof(struct atag_header) + linelen + 1 + 4) >> 2; 00130 00131 strcpy(_params->u.cmdline.cmdline,line); /* place commandline into tag */ 00132 00133 _params = tag_next(_params); /* move pointer to next tag */ 00134 } 00135 00136 static void setup_mem_tag( uint32_t start, uint32_t len ) 00137 { 00138 printh("setup_mem_tag start : %x len : %x\n", start, len); 00139 _params->hdr.tag = ATAG_MEM; /* Memory tag */ 00140 _params->hdr.size = tag_size(atag_mem); /* size tag */ 00141 00142 _params->u.mem.start = start; /* Start of memory area (physical address) */ 00143 _params->u.mem.size = len; /* Length of area */ 00144 00145 _params = tag_next(_params); /* move pointer to next tag */ 00146 } 00147 00148 static void setup_end_tag( void ) 00149 { 00150 _params->hdr.tag = ATAG_NONE; /* Empty tag ends list */ 00151 _params->hdr.size = 0; /* zero length */ 00152 } 00153 00154 void loadlinux_setup_tags( uint32_t *src ) 00155 { 00156 char *commandline = "root=/dev/ram rw earlyprintk console=ttyAMA0 mem=256M rdinit=/sbin/init"; 00157 setup_core_tag(src+(0x100/4), 4096); /* standard core tag 4k pagesize */ 00158 setup_cmdline_tag(commandline); /* commandline setting root device */ 00159 setup_revision_tag(); 00160 setup_mem_tag((uint32_t)(src-(0x20000000/4)), 0x10000000); 00161 /* end of tags */ 00162 setup_end_tag(); 00163 }