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 = ± 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 -