jrw@uncecs.edu (James R. White) (03/25/90)
When using Turbo C to compile 1.5.5, there is a bug when trying to use protected mode. There are several places where a pointer is converted to a long with a cast, such as: (phys_bytes) some_pointer (where phys_bytes is typedefed to long) Now Turbo C has a large model mentality even when compiling for the tiny model, so it assigns the large model form of the pointer to the long. So while minix assumes the high order part will be zero, TC sets it to the value in the segment register. The fix I used was to cast the pointer to an int, and then to a long. With this fix (and the previously posted mpx fix) I am now able to boot my TC compiled minix 1.5.5 in both real and protected mode. Here are the diffs for protect1.c and protect.c ------------------------------ protect1.c -------------------------- 77c77 < data_base + (phys_bytes) rp->p_ldt, --- > data_base + (phys_bytes)(int) rp->p_ldt, ------------------------------ protect.c --------------------------- 156,159c156,159 < data_base + (phys_bytes) gdt; < ((struct desctableptr_s *) &gdt[BIOS_IDT_INDEX])->limit = sizeof idt - 1; < ((struct desctableptr_s *) &gdt[BIOS_IDT_INDEX])->base = < data_base + (phys_bytes) idt; --- > data_base + (phys_bytes)(int) gdt; > ((struct desctableptr_s *) &gdt[BIOS_IDT_INDEX])->limit = sizeof idt - 1; > ((struct desctableptr_s *) &gdt[BIOS_IDT_INDEX])->base = > data_base + (phys_bytes)(int) idt; 172c172 < init_dataseg(&gdt[GDT_INDEX], data_base + (phys_bytes) gdt, --- > init_dataseg(&gdt[GDT_INDEX], data_base + (phys_bytes)(int) gdt, 195c195 < init_dataseg(&gdt[TSS_INDEX], data_base + (phys_bytes) &tss, --- > init_dataseg(&gdt[TSS_INDEX], data_base + (phys_bytes)(int) &tss, 202,205c202,205 < int_gate(gtp->vec_nr, (phys_bytes) gtp->gate, < PRESENT | INT_GATE_TYPE | (gtp->privilege << DPL_SHIFT)); < } < int_gate(SYS_VECTOR, (phys_bytes) p_s_call, --- > int_gate(gtp->vec_nr, (phys_bytes)(int) gtp->gate, > PRESENT | INT_GATE_TYPE | (gtp->privilege << DPL_SHIFT)); > } > int_gate(SYS_VECTOR, (phys_bytes)(int) p_s_call, 224c224 < int_gate(SYS386_VECTOR, (phys_bytes) s_call, --- > int_gate(SYS386_VECTOR, (phys_bytes)(int) s_call, -----------------------------------------------------------------
jrw@uncecs.edu (James R. White) (03/25/90)
[problem with Turbo C 2.0 compiling 1.5.5 where a pointer would be cast to a long and TC would put the segment in the upper part.] Oops. My solution was to cast to an (int) before casting to a (long). Bruce Evans has pointed out to me that casting to an (unsigned) would be better because (long)(int) will sign extend while (long)(unsigned) won't. I got away with (int) because I'm using separate I&D and so all the pointers being converted were less than 0x8000.