wok diff linld/stuff/load.u @ rev 20256

Add tlp
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Mar 13 23:01:20 2018 +0100 (2018-03-13)
parents df186455938f
children e93e6b4d565f
line diff
     1.1 --- a/linld/stuff/load.u	Sat Jun 11 20:26:42 2016 +0200
     1.2 +++ b/linld/stuff/load.u	Tue Mar 13 23:01:20 2018 +0100
     1.3 @@ -1,6 +1,135 @@
     1.4  --- LINLD097/LOAD.CPP
     1.5  +++ LINLD097/LOAD.CPP
     1.6 -@@ -400,10 +400,8 @@
     1.7 +@@ -10,12 +10,21 @@
     1.8 +     if(cnt != size) die(msg);
     1.9 + }
    1.10 + 
    1.11 +-static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
    1.12 +-    int fd = open(fn, O_RDONLY|O_BINARY);
    1.13 +-    if(fd == -1) die(msg);
    1.14 +-    u32 size = lseek(fd,0,SEEK_END);
    1.15 +-    if(s32(size)==-1L) die(msg);
    1.16 ++static int openimage(const char *name, const char *failmsg, u32 *size) {
    1.17 ++    int fd = open(name, O_RDONLY|O_BINARY);
    1.18 ++    if(fd != -1) {
    1.19 ++        *size = lseek(fd,0,SEEK_END);
    1.20 ++        if(s32(*size)!=-1L) goto gotimage;
    1.21 ++    }
    1.22 ++    die(failmsg);
    1.23 ++  gotimage:
    1.24 +     lseek(fd,0,SEEK_SET);
    1.25 ++    return fd;
    1.26 ++}
    1.27 ++
    1.28 ++static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
    1.29 ++    u32 size;
    1.30 ++    int fd = openimage(fn, msg, &size);
    1.31 +     if(size>=maxsz) die(msg);
    1.32 +     char *buf = malloc_or_die(size+1, msg); // +1 for '\0'
    1.33 +     read_or_die(fd, buf, size, msg);
    1.34 +@@ -188,7 +197,7 @@
    1.35 +     u8      pad30[0x400-0x22c]; // 022C
    1.36 +                             // 02D0 up to 32 20-byte mem info structs from
    1.37 +                             // int 0x15 fn 0xe820
    1.38 +-}; //__attribute((packed));
    1.39 ++} *first1k; //__attribute((packed));
    1.40 + 
    1.41 + #if sizeof(first1k_t)!=0x400
    1.42 + #error BUG: Bad first1k
    1.43 +@@ -219,7 +228,7 @@
    1.44 + 
    1.45 + // Called from inside kernel just before rm->pm
    1.46 + // _loadds _saveregs: done by hand
    1.47 +-static void far last_ditch() {
    1.48 ++void far last_ditch() {
    1.49 +     cli();  // we start doing *really* destructive things to DOS/BIOS
    1.50 +             // it means: do not even try to enable ints
    1.51 +             // or call BIOS services after this
    1.52 +@@ -296,6 +305,11 @@
    1.53 +         "\tvga=0" NL
    1.54 +         "Use quotes: \"cl=...\" if you need spaces in cmdline" NL
    1.55 +         "Use cl=@filename to take cmdline from file"
    1.56 ++#if 0
    1.57 ++        NL NL "Example" NL
    1.58 ++        "\tcopy/b rootfs4.gz+rootfs3.gz+rootfs2.gz+rootfs1.gz rootfs.gz" NL
    1.59 ++        "\tlinld initrd=rootfs.gz \"cl=rw root=/dev/null video=-32\""
    1.60 ++#endif
    1.61 +     );
    1.62 + }
    1.63 + 
    1.64 +@@ -331,7 +345,10 @@
    1.65 + 
    1.66 +     // Parse command line
    1.67 + 
    1.68 +-    if(argc<2) syntax();
    1.69 ++    if(argc<2) {
    1.70 ++dosyntax:
    1.71 ++        syntax();
    1.72 ++    }
    1.73 + #define STRNCMP(a,b) strncmp((a),(b),sizeof(b)-1)
    1.74 +     {for(int i=1;i<argc;i++) {
    1.75 +         if(STRNCMP(argv[i],"image=") == 0) {
    1.76 +@@ -340,28 +357,23 @@
    1.77 +         else if(STRNCMP(argv[i],"initrd=") == 0) {
    1.78 +             initrd_name=argv[i]+7;
    1.79 +         }
    1.80 +-        else if(STRNCMP(argv[i],"cl=@") == 0) {
    1.81 +-            cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
    1.82 +-            puts("Kernel command line:");
    1.83 +-            puts(cmdline);
    1.84 +-        }
    1.85 +         else if(STRNCMP(argv[i],"cl=") == 0) {
    1.86 +             cmdline=argv[i]+3;
    1.87 ++            if (cmdline[0] == '@') {
    1.88 ++                cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
    1.89 ++                puts("Kernel command line:");
    1.90 ++                puts(cmdline);
    1.91 ++            }
    1.92 +         }
    1.93 +-        else if(strcmp(argv[i],"vga=ask") == 0) {
    1.94 +-            vid_mode = -3;
    1.95 +-        }
    1.96 +-        else if(strcmp(argv[i],"vga=extended") == 0) {
    1.97 +-            vid_mode = -2;
    1.98 +-        }
    1.99 +-        else if(strcmp(argv[i],"vga=normal") == 0) {
   1.100 +-            vid_mode = -1;
   1.101 +-        }
   1.102 +         else if(STRNCMP(argv[i],"vga=") == 0) {
   1.103 +-            vid_mode = strtoul(argv[i]+4);
   1.104 ++	    const char *s=argv[i]+4;
   1.105 ++            if (*s == 'a') vid_mode = -3;
   1.106 ++            else if (*s == 'e') vid_mode = -2;
   1.107 ++            else if (*s == 'n') vid_mode = -1;
   1.108 ++            else vid_mode = strtoul(s);
   1.109 +         }
   1.110 +         else
   1.111 +-            syntax();
   1.112 ++            goto dosyntax;
   1.113 +     }}
   1.114 + #undef STRNCMP
   1.115 + 
   1.116 +@@ -384,15 +396,12 @@
   1.117 + 
   1.118 +     rm_buf = malloc_or_die(_32k, "Can't allocate rm buf");
   1.119 +     // Do not use malloc below until heap_top adjustment (see <*>)
   1.120 +-    int fd = open(kernel_name, O_RDONLY|O_BINARY);
   1.121 +-    if(fd == -1) die("Can't open kernel file");
   1.122 +-    u32 image_size = lseek(fd,0,SEEK_END);
   1.123 +-    if(s32(image_size)==-1L) die("Can't seek kernel file");
   1.124 +-    lseek(fd,0,SEEK_SET);
   1.125 ++    u32 image_size;
   1.126 ++    int fd = openimage(kernel_name, "Can't use kernel file", &image_size);
   1.127 +     read_or_die(fd, rm_buf, 0x400, "Can't read first kb");
   1.128 + 
   1.129 +-    struct first1k_t* first1k = (first1k_t*)rm_buf;
   1.130 +-    // new kernels never need: if(!first1k->setup_sects) first1k->setup_sects=4;
   1.131 ++    first1k = (first1k_t*)rm_buf;
   1.132 ++    if(!first1k->setup_sects) first1k->setup_sects=4;
   1.133 +     rm_size = 0x200*(first1k->setup_sects+1); // 0th sector is not counted there
   1.134 +     if(rm_size>_32k)
   1.135 +         die("rm_size is too big");
   1.136 +@@ -400,33 +409,46 @@
   1.137   
   1.138       if(first1k->boot_flag != 0xAA55)
   1.139           die("No boot signature (55,AA). It's not a kernel");
   1.140 @@ -8,37 +137,89 @@
   1.141  -        die("No 'HdrS' signature (kernel is too old)");
   1.142  -    if(first1k->version < 0x202)
   1.143  -        die("Loader protocol version is less than 2.02 (kernel is too old)");
   1.144 -+    if(first1k->header != HdrS) // starting linux 1.3.73
   1.145 -+        die("No 'HdrS' signature (kernel is too old, try /usr/bin/tobzimage)");
   1.146 -     if(!(first1k->loadflags & 0x01))
   1.147 -         die("I can't load bzImages low");
   1.148 +-    if(!(first1k->loadflags & 0x01))
   1.149 +-        die("I can't load bzImages low");
   1.150   
   1.151 -@@ -414,15 +412,23 @@
   1.152 +-    // Read remaining rm loader
   1.153 +-
   1.154 +-    read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
   1.155 +-
   1.156       // Tell rm loader some info
   1.157   
   1.158       first1k->vid_mode = vid_mode;
   1.159  -    first1k->cmd_line_ptr = 0x98000;
   1.160 -+    if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
   1.161 -+        first1k->cmd_line_ptr = 0x98000;
   1.162 -+    }
   1.163 -+    else {
   1.164 -+        first1k->cl_magic = 0xA33F;
   1.165 -+        first1k->cl_ofs   = 0x8000;
   1.166 -+    }
   1.167 -     first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
   1.168 -     // * will be called just before rm -> pm
   1.169 -     first1k->realmode_switch_ofs = ofs(last_ditch);
   1.170 -     first1k->realmode_switch_seg = seg(last_ditch);
   1.171 +-    first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
   1.172 +-    // * will be called just before rm -> pm
   1.173 +-    first1k->realmode_switch_ofs = ofs(last_ditch);
   1.174 +-    first1k->realmode_switch_seg = seg(last_ditch);
   1.175  -    // * offset limit of the setup heap
   1.176  -    //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
   1.177  -    first1k->heap_end_ptr = _32k-0x0200;
   1.178  -    first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
   1.179 -+    if(first1k->version >= 0x201) {
   1.180 -+        // * offset limit of the setup heap
   1.181 -+        //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
   1.182 -+        first1k->heap_end_ptr = _32k-0x0200;
   1.183 -+        first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
   1.184 +-    // * if we will ever stop moving ourself to 0x90000
   1.185 +-    //   we must say setup.S how much to move
   1.186 +-    //first1k->setup_move_size = _32k;
   1.187 ++#if 1
   1.188 ++    if(first1k->header == HdrS) { // starting linux 1.3.73
   1.189 ++	if(first1k->loadflags & 1) {
   1.190 ++#else
   1.191 ++    if((first1k->header != HdrS) || (first1k->loadflags & 1) == 0)
   1.192 ++        die("I can't load bzImage low");
   1.193 ++    {
   1.194 ++        {
   1.195 ++#endif
   1.196 ++            first1k->realmode_switch_ofs = ofs(last_ditch);
   1.197 ++            first1k->realmode_switch_seg = seg(last_ditch);
   1.198 ++        }
   1.199 ++        first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
   1.200 ++        // * will be called just before rm -> pm
   1.201 ++        if(first1k->version >= 0x201) {
   1.202 ++            // * offset limit of the setup heap
   1.203 ++            //   heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
   1.204 ++            first1k->heap_end_ptr = _32k-0x0200;
   1.205 ++            first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
   1.206 ++        }
   1.207 ++        // * if we will ever stop moving ourself to 0x90000
   1.208 ++        //   we must say setup.S how much to move
   1.209 ++        //first1k->setup_move_size = _32k;
   1.210 ++        if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
   1.211 ++            first1k->cmd_line_ptr = 0x98000;
   1.212 ++            goto cmd_line_ok;
   1.213 ++        }
   1.214  +    }
   1.215 -     // * if we will ever stop moving ourself to 0x90000
   1.216 -     //   we must say setup.S how much to move
   1.217 -     //first1k->setup_move_size = _32k;
   1.218 ++    first1k->cl_magic = 0xA33F;
   1.219 ++    first1k->cl_ofs   = 0x8000;
   1.220 + 
   1.221 ++cmd_line_ok:
   1.222 ++    // Read remaining rm loader
   1.223 ++
   1.224 ++    read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
   1.225 ++
   1.226 +     // Read remaining kernel (pm part)
   1.227 +     // Try to load kernel high, maybe even blindly storing it
   1.228 +     // in unallocated memory as a last resort
   1.229 +@@ -449,11 +471,7 @@
   1.230 +     // Read initrd if needed
   1.231 + 
   1.232 +     if(initrd_name) {
   1.233 +-        int fd = open(initrd_name, O_RDONLY|O_BINARY);
   1.234 +-        if(fd == -1) die("Can't open initrd file");
   1.235 +-        initrd_size = lseek(fd,0,SEEK_END);
   1.236 +-        if(s32(initrd_size)==-1L) die("Can't seek initrd file");
   1.237 +-        lseek(fd,0,SEEK_SET);
   1.238 ++        int fd = openimage(initrd_name, "Can't use initrd file", &initrd_size);
   1.239 +         initrd_target_addr = (memtop()-initrd_size) & (~PAGE_MASK);
   1.240 +       //not needed: kernel detects this and drops initrd
   1.241 +       //// assume 2:1 decompression ratio
   1.242 +@@ -520,9 +538,9 @@
   1.243 + 
   1.244 +     // Jump to kernel rm code
   1.245 +     set_sregs_jump_seg_ofs(
   1.246 +-        0x9000,     //sregs
   1.247 ++        0x9020,0,   //cs,ip
   1.248 +         0xA000,     //sp
   1.249 +-        0x9020,0    //cs,ip
   1.250 ++        0x9000      //sregs
   1.251 +     );
   1.252 + 
   1.253 +     // Let compiler be happy