wok annotate linld/stuff/load.u @ rev 20106

dropbear: typo
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Oct 09 21:35:33 2017 +0200 (2017-10-09)
parents df186455938f
children e93e6b4d565f
rev   line source
pascal@17446 1 --- LINLD097/LOAD.CPP
pascal@17446 2 +++ LINLD097/LOAD.CPP
pascal@19465 3 @@ -10,12 +10,21 @@
pascal@19465 4 if(cnt != size) die(msg);
pascal@19465 5 }
pascal@19465 6
pascal@19465 7 -static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
pascal@19465 8 - int fd = open(fn, O_RDONLY|O_BINARY);
pascal@19465 9 - if(fd == -1) die(msg);
pascal@19465 10 - u32 size = lseek(fd,0,SEEK_END);
pascal@19465 11 - if(s32(size)==-1L) die(msg);
pascal@19465 12 +static int openimage(const char *name, const char *failmsg, u32 *size) {
pascal@19465 13 + int fd = open(name, O_RDONLY|O_BINARY);
pascal@19465 14 + if(fd != -1) {
pascal@19465 15 + *size = lseek(fd,0,SEEK_END);
pascal@19465 16 + if(s32(*size)!=-1L) goto gotimage;
pascal@19465 17 + }
pascal@19465 18 + die(failmsg);
pascal@19465 19 + gotimage:
pascal@19465 20 lseek(fd,0,SEEK_SET);
pascal@19465 21 + return fd;
pascal@19465 22 +}
pascal@19465 23 +
pascal@19465 24 +static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
pascal@19465 25 + u32 size;
pascal@19465 26 + int fd = openimage(fn, msg, &size);
pascal@19465 27 if(size>=maxsz) die(msg);
pascal@19465 28 char *buf = malloc_or_die(size+1, msg); // +1 for '\0'
pascal@19465 29 read_or_die(fd, buf, size, msg);
pascal@19465 30 @@ -188,7 +197,7 @@
pascal@19465 31 u8 pad30[0x400-0x22c]; // 022C
pascal@19465 32 // 02D0 up to 32 20-byte mem info structs from
pascal@19465 33 // int 0x15 fn 0xe820
pascal@19465 34 -}; //__attribute((packed));
pascal@19465 35 +} *first1k; //__attribute((packed));
pascal@19465 36
pascal@19465 37 #if sizeof(first1k_t)!=0x400
pascal@19465 38 #error BUG: Bad first1k
pascal@19465 39 @@ -219,7 +228,7 @@
pascal@19465 40
pascal@19465 41 // Called from inside kernel just before rm->pm
pascal@19465 42 // _loadds _saveregs: done by hand
pascal@19465 43 -static void far last_ditch() {
pascal@19465 44 +void far last_ditch() {
pascal@19465 45 cli(); // we start doing *really* destructive things to DOS/BIOS
pascal@19465 46 // it means: do not even try to enable ints
pascal@19465 47 // or call BIOS services after this
pascal@19465 48 @@ -296,6 +305,11 @@
pascal@19465 49 "\tvga=0" NL
pascal@19465 50 "Use quotes: \"cl=...\" if you need spaces in cmdline" NL
pascal@19465 51 "Use cl=@filename to take cmdline from file"
pascal@19465 52 +#if 0
pascal@19465 53 + NL NL "Example" NL
pascal@19465 54 + "\tcopy/b rootfs4.gz+rootfs3.gz+rootfs2.gz+rootfs1.gz rootfs.gz" NL
pascal@19465 55 + "\tlinld initrd=rootfs.gz \"cl=rw root=/dev/null video=-32\""
pascal@19465 56 +#endif
pascal@19465 57 );
pascal@19465 58 }
pascal@19465 59
pascal@19465 60 @@ -331,7 +345,10 @@
pascal@19465 61
pascal@19465 62 // Parse command line
pascal@19465 63
pascal@19465 64 - if(argc<2) syntax();
pascal@19465 65 + if(argc<2) {
pascal@19465 66 +dosyntax:
pascal@19465 67 + syntax();
pascal@19465 68 + }
pascal@19465 69 #define STRNCMP(a,b) strncmp((a),(b),sizeof(b)-1)
pascal@19465 70 {for(int i=1;i<argc;i++) {
pascal@19465 71 if(STRNCMP(argv[i],"image=") == 0) {
pascal@19465 72 @@ -340,28 +357,23 @@
pascal@19465 73 else if(STRNCMP(argv[i],"initrd=") == 0) {
pascal@19465 74 initrd_name=argv[i]+7;
pascal@19465 75 }
pascal@19465 76 - else if(STRNCMP(argv[i],"cl=@") == 0) {
pascal@19465 77 - cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
pascal@19465 78 - puts("Kernel command line:");
pascal@19465 79 - puts(cmdline);
pascal@19465 80 - }
pascal@19465 81 else if(STRNCMP(argv[i],"cl=") == 0) {
pascal@19465 82 cmdline=argv[i]+3;
pascal@19465 83 + if (cmdline[0] == '@') {
pascal@19465 84 + cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
pascal@19465 85 + puts("Kernel command line:");
pascal@19465 86 + puts(cmdline);
pascal@19465 87 + }
pascal@19465 88 }
pascal@19465 89 - else if(strcmp(argv[i],"vga=ask") == 0) {
pascal@19465 90 - vid_mode = -3;
pascal@19465 91 - }
pascal@19465 92 - else if(strcmp(argv[i],"vga=extended") == 0) {
pascal@19465 93 - vid_mode = -2;
pascal@19465 94 - }
pascal@19465 95 - else if(strcmp(argv[i],"vga=normal") == 0) {
pascal@19465 96 - vid_mode = -1;
pascal@19465 97 - }
pascal@19465 98 else if(STRNCMP(argv[i],"vga=") == 0) {
pascal@19465 99 - vid_mode = strtoul(argv[i]+4);
pascal@19465 100 + const char *s=argv[i]+4;
pascal@19465 101 + if (*s == 'a') vid_mode = -3;
pascal@19465 102 + else if (*s == 'e') vid_mode = -2;
pascal@19465 103 + else if (*s == 'n') vid_mode = -1;
pascal@19465 104 + else vid_mode = strtoul(s);
pascal@19465 105 }
pascal@19465 106 else
pascal@19465 107 - syntax();
pascal@19465 108 + goto dosyntax;
pascal@19465 109 }}
pascal@19465 110 #undef STRNCMP
pascal@19465 111
pascal@19465 112 @@ -384,15 +396,12 @@
pascal@19465 113
pascal@19465 114 rm_buf = malloc_or_die(_32k, "Can't allocate rm buf");
pascal@19465 115 // Do not use malloc below until heap_top adjustment (see <*>)
pascal@19465 116 - int fd = open(kernel_name, O_RDONLY|O_BINARY);
pascal@19465 117 - if(fd == -1) die("Can't open kernel file");
pascal@19465 118 - u32 image_size = lseek(fd,0,SEEK_END);
pascal@19465 119 - if(s32(image_size)==-1L) die("Can't seek kernel file");
pascal@19465 120 - lseek(fd,0,SEEK_SET);
pascal@19465 121 + u32 image_size;
pascal@19465 122 + int fd = openimage(kernel_name, "Can't use kernel file", &image_size);
pascal@19465 123 read_or_die(fd, rm_buf, 0x400, "Can't read first kb");
pascal@19465 124
pascal@19465 125 - struct first1k_t* first1k = (first1k_t*)rm_buf;
pascal@19465 126 - // new kernels never need: if(!first1k->setup_sects) first1k->setup_sects=4;
pascal@19465 127 + first1k = (first1k_t*)rm_buf;
pascal@19465 128 + if(!first1k->setup_sects) first1k->setup_sects=4;
pascal@19465 129 rm_size = 0x200*(first1k->setup_sects+1); // 0th sector is not counted there
pascal@19465 130 if(rm_size>_32k)
pascal@19465 131 die("rm_size is too big");
pascal@19465 132 @@ -400,33 +409,46 @@
pascal@17446 133
pascal@17446 134 if(first1k->boot_flag != 0xAA55)
pascal@17446 135 die("No boot signature (55,AA). It's not a kernel");
pascal@17446 136 - if(first1k->header != HdrS)
pascal@18228 137 - die("No 'HdrS' signature (kernel is too old)");
pascal@17446 138 - if(first1k->version < 0x202)
pascal@17446 139 - die("Loader protocol version is less than 2.02 (kernel is too old)");
pascal@19465 140 - if(!(first1k->loadflags & 0x01))
pascal@19465 141 - die("I can't load bzImages low");
pascal@17446 142
pascal@19465 143 - // Read remaining rm loader
pascal@19465 144 -
pascal@19465 145 - read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
pascal@19465 146 -
pascal@17446 147 // Tell rm loader some info
pascal@17446 148
pascal@17446 149 first1k->vid_mode = vid_mode;
pascal@17446 150 - first1k->cmd_line_ptr = 0x98000;
pascal@19465 151 - first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
pascal@19465 152 - // * will be called just before rm -> pm
pascal@19465 153 - first1k->realmode_switch_ofs = ofs(last_ditch);
pascal@19465 154 - first1k->realmode_switch_seg = seg(last_ditch);
pascal@19204 155 - // * offset limit of the setup heap
pascal@19204 156 - // heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
pascal@19204 157 - first1k->heap_end_ptr = _32k-0x0200;
pascal@19204 158 - first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
pascal@19465 159 - // * if we will ever stop moving ourself to 0x90000
pascal@19465 160 - // we must say setup.S how much to move
pascal@19465 161 - //first1k->setup_move_size = _32k;
pascal@19465 162 +#if 1
pascal@19465 163 + if(first1k->header == HdrS) { // starting linux 1.3.73
pascal@19465 164 + if(first1k->loadflags & 1) {
pascal@19465 165 +#else
pascal@19465 166 + if((first1k->header != HdrS) || (first1k->loadflags & 1) == 0)
pascal@19465 167 + die("I can't load bzImage low");
pascal@19465 168 + {
pascal@19465 169 + {
pascal@19465 170 +#endif
pascal@19465 171 + first1k->realmode_switch_ofs = ofs(last_ditch);
pascal@19465 172 + first1k->realmode_switch_seg = seg(last_ditch);
pascal@19465 173 + }
pascal@19465 174 + first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
pascal@19465 175 + // * will be called just before rm -> pm
pascal@19465 176 + if(first1k->version >= 0x201) {
pascal@19465 177 + // * offset limit of the setup heap
pascal@19465 178 + // heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
pascal@19465 179 + first1k->heap_end_ptr = _32k-0x0200;
pascal@19465 180 + first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
pascal@19465 181 + }
pascal@19465 182 + // * if we will ever stop moving ourself to 0x90000
pascal@19465 183 + // we must say setup.S how much to move
pascal@19465 184 + //first1k->setup_move_size = _32k;
pascal@19465 185 + if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
pascal@19465 186 + first1k->cmd_line_ptr = 0x98000;
pascal@19465 187 + goto cmd_line_ok;
pascal@19465 188 + }
pascal@19204 189 + }
pascal@19465 190 + first1k->cl_magic = 0xA33F;
pascal@19465 191 + first1k->cl_ofs = 0x8000;
pascal@19465 192
pascal@19465 193 +cmd_line_ok:
pascal@19465 194 + // Read remaining rm loader
pascal@19465 195 +
pascal@19465 196 + read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
pascal@19465 197 +
pascal@19465 198 // Read remaining kernel (pm part)
pascal@19465 199 // Try to load kernel high, maybe even blindly storing it
pascal@19465 200 // in unallocated memory as a last resort
pascal@19465 201 @@ -449,11 +471,7 @@
pascal@19465 202 // Read initrd if needed
pascal@19465 203
pascal@19465 204 if(initrd_name) {
pascal@19465 205 - int fd = open(initrd_name, O_RDONLY|O_BINARY);
pascal@19465 206 - if(fd == -1) die("Can't open initrd file");
pascal@19465 207 - initrd_size = lseek(fd,0,SEEK_END);
pascal@19465 208 - if(s32(initrd_size)==-1L) die("Can't seek initrd file");
pascal@19465 209 - lseek(fd,0,SEEK_SET);
pascal@19465 210 + int fd = openimage(initrd_name, "Can't use initrd file", &initrd_size);
pascal@19465 211 initrd_target_addr = (memtop()-initrd_size) & (~PAGE_MASK);
pascal@19465 212 //not needed: kernel detects this and drops initrd
pascal@19465 213 //// assume 2:1 decompression ratio
pascal@19465 214 @@ -520,9 +538,9 @@
pascal@19465 215
pascal@19465 216 // Jump to kernel rm code
pascal@19465 217 set_sregs_jump_seg_ofs(
pascal@19465 218 - 0x9000, //sregs
pascal@19465 219 + 0x9020,0, //cs,ip
pascal@19465 220 0xA000, //sp
pascal@19465 221 - 0x9020,0 //cs,ip
pascal@19465 222 + 0x9000 //sregs
pascal@19465 223 );
pascal@19465 224
pascal@19465 225 // Let compiler be happy