wok-current diff linld/stuff/src/HIMEM.CPP @ rev 19571

linld: large image support with VCPI
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Dec 22 21:06:17 2016 +0100 (2016-12-22)
parents d934532a1be1
children 23fc786c04e8
line diff
     1.1 --- a/linld/stuff/src/HIMEM.CPP	Sat Dec 17 19:13:29 2016 +0100
     1.2 +++ b/linld/stuff/src/HIMEM.CPP	Thu Dec 22 21:06:17 2016 +0100
     1.3 @@ -6,6 +6,81 @@
     1.4  #include "crtl.h"
     1.5  #include "common.h"
     1.6  
     1.7 +struct image_himem pm;
     1.8 +struct image_himem initrd;
     1.9 +
    1.10 +// Called from inside kernel just before rm->pm
    1.11 +// _loadds _saveregs: done by hand
    1.12 +void far last_ditch() {
    1.13 +    cli();  // we start doing *really* destructive things to DOS/BIOS
    1.14 +            // it means: do not even try to enable ints
    1.15 +            // or call BIOS services after this
    1.16 +    asm {
    1.17 +        push    ds
    1.18 +        push    cs
    1.19 +        pop     ds
    1.20 +#ifndef NO386
    1.21 +        pusha
    1.22 +#else
    1.23 +        push	ax
    1.24 +        push	bx
    1.25 +        push	cx
    1.26 +        push	dx
    1.27 +#endif
    1.28 +    }
    1.29 +    struct image_himem *m = &pm;
    1.30 +    if(((u16 *)&m->fallback)[1] >= 0x10) m->fallback = _1m; // >= _1m ?
    1.31 +    if(vcpi==0) {
    1.32 +        // Move kernel
    1.33 +        memcpy_image(m);
    1.34 +        // Move initrd
    1.35 +        memcpy_image(&initrd);
    1.36 +    } else { //vcpi
    1.37 +        vm2rm();
    1.38 +        // Move kernel
    1.39 +        // 'Gathering' copy in chunks of PAGE_SIZE
    1.40 +        // No risk of overlapping: kernel is copied from above to 1m mark
    1.41 +        m->size = initrd.size = PAGE_SIZE;
    1.42 +        u32 *p = m->bufv;
    1.43 +	reset_bufv(p);
    1.44 +	if (p) do {
    1.45 +            m->buf = *p;
    1.46 +            memcpy_image(m);
    1.47 +            next(p); m->fallback+=PAGE_SIZE;
    1.48 +        } while(*p);
    1.49 +        // Move initrd
    1.50 +	m = &initrd;
    1.51 +        if(m->fallback) {
    1.52 +            // This is tricky: copy initrd backwards to reduce
    1.53 +            // risk of overlapping: use the fact that initrd is copied
    1.54 +            // to the very top of ram
    1.55 +            // (overlapping still can happen with more than 256mb ram)
    1.56 +            // (generic solution for this overwrite problem, anyone?)
    1.57 +            p=m->bufv;
    1.58 +	    reset_bufv(p);
    1.59 +            do {
    1.60 +                next(p); m->fallback+=PAGE_SIZE;
    1.61 +            } while(*p);
    1.62 +            do {
    1.63 +                prev(p); m->fallback-=PAGE_SIZE;
    1.64 +                m->buf = *p;
    1.65 +                memcpy_image(m);
    1.66 +            } while(p != m->bufv);
    1.67 +        }
    1.68 +    }
    1.69 +    asm {
    1.70 +#ifndef NO386
    1.71 +        popa
    1.72 +#else
    1.73 +        pop	dx
    1.74 +        pop	cx
    1.75 +        pop	bx
    1.76 +        pop	ax
    1.77 +#endif
    1.78 +        pop     ds
    1.79 +    }
    1.80 +}
    1.81 +
    1.82  int skip_xmmalloc;
    1.83  void load_image(struct image_himem *m) {
    1.84      no_exit++;       // die() won't return to DOS
    1.85 @@ -13,7 +88,7 @@
    1.86      m->buf = m->fallback;
    1.87      u32 buf;
    1.88      u32* bufv= &buf;
    1.89 -    if(m->fallback >= _1m) {
    1.90 +    if(((u16 *)&m->fallback)[1] >= 0x10) { // >= _1m ?
    1.91  	if(vcpi) {
    1.92  	    bufv = malloc_bufv_or_die(m);	// update m->bufv
    1.93  	}
    1.94 @@ -24,13 +99,12 @@
    1.95      buf = m->buf;
    1.96      do {
    1.97  	u8 xfer_buf[PAGE_SIZE];
    1.98 -        u16 size = read_image(m, xfer_buf, PAGE_SIZE);
    1.99 -        if(s16(size) <= 0) break;
   1.100 -        memcpy32(*bufv, seg(xfer_buf), ofs(xfer_buf), PAGE_SIZE);
   1.101 -	if (bufv != &buf) bufv++;
   1.102 +        u16 size;
   1.103 +	if(s16(size = read_image(m, xfer_buf, PAGE_SIZE)) <= 0) break;
   1.104 +        storepage(bufv, ofs(xfer_buf));
   1.105 +	if (bufv != &buf) next(bufv);
   1.106          buf += size;
   1.107      } while (*bufv);
   1.108      if(m->remaining) die("Read error");
   1.109      close(m->fd2close);
   1.110  }
   1.111 -