johnc@rtmvax.UUCP (John Connin) (01/26/89)
In message <1944@ast.cs.vu.nl> Andy Tanenbaum writes: [ stuff deleted ] > Hardware types, get out your thinking caps. > > Another point, I am still trying to figure out exactly how to tell if > a machine is (1) PS/2 and (2) Microchannel. Several people have pointed > out that INT 15 is supposed to tell you, but I can't find that in my > (PC) BIOS manual. Maybe it is something new. Could some kind soul please [ stuff deleted ] First, as a policy, I believe that Minix should NOT rely on BIOS services. Yes, I know it makes life easier, but my feeling is that doing so detracts from the beauty of Minix. As to AST's question, though not comprehensive, perhaps the follow code fragments will help. One determines the processor type by executing selected instructions. The other determines the machine type by testing the 'model byte' located at 0xFFFF:000E. Perhaps someone more knowledgeable than myself can contribute a comprehensive model byte list. An additional piece of information (clone type) can be had by checking the BIOS 'id_string' at 0xF000:0xFFEA (eg. "IBM", "COMPAQ", "OLIVETTI",..). As an addition thought, I believe it would be prudent to collect all low level "survey code" into one code module. As envisioned, this code would be called by kernel/main and would place results in a "system data" structure which is accessable to all other OS modules. To illustrate the point, consider the following code fragement and system data structure which is evolving in my own version of Minix: survey_enviroment() { /* find out our equipment configuration */ equip_check(); /* get the io port address */ serial_ports(); printer_ports(); /* get the memory parameters */ mem_parms(); /* get the hard disk parameters */ hdisk_parms(); } /* Global System Data */ struct sysdat { ... int cur_proc; int prev_proc; long realtime; /* -- memory section -- */ uint base_mem; /* amount of base memory (kb) */ uint extended_mem; /* amount of extended memory (kb) */ phys_clicks minix_base; /* where minix starts in memory */ vir_clicks minix_size; /* length of memory image exclusive */ /* of RAM disk */ phys_clicks init_text_org; vir_clicks init_text_size; phys_clicks init_data_org; vir_clicks init_data_size; /* -- general equipment section -- */ int nr_fdisks; int nr_hdisks; int nr_serial; int nr_parallel; int nr_mono; int nr_color; int nr_ndp; /* numeric processor */ int serial_ports[ MAX_PORTS]; /* port addresses */ int parallel_ports[ MAX_PORTS]; /* -- video section -- */ int vio_boot_mode; /* 00 = EGA, 01 = CGA-40 */ /* 10 = CGA-80, 11 = MDA-80 */ int vio_cur_mode; int vio_segment; int vio_sync; int ega_config; int ega_memsize; int ega_switch; int ega_feature; uint herc_retrace; /* hercules retrace timing */ /* -- hard disk parameters -- */ struct hd_parm hdisk_tbl[ MAX_HDISK]; ... }; After 'sysdat' is initialized, each module is initialized in turn and the address of 'sysdat' is passed as an argument ( even to those modules which occupy a different address space, eg. mm and fs). _mmgr_init: mov word ptr DGROUP:_sysdata, bx ; store address of struct sys_dat mov word ptr DGROUP:_sysdata+2,dx ; call _mm_init retf mm_init() { /* create the memory manager process */ if ((mm_procnr = create((struct pdesc far *) &mm_pdesc)) == -1) { kprintf(fpString("Can't create process: memory manager\n")); } else { if (ready(mm_procnr) != OK) return( -1 ); } return( OK ); } mm_server() { int error; init_mm(); /* initialize memory manager tables */ /* This is MM's main loop - get work and do it, forever.. */ while (TRUE) { /* Wait for message. */ get_work(); /* wait for an MM system call */ ..... } } Well I have stray too far from the intended focus of this message, so I will stop at this point. ---------------------------------------------------------------- processor_type: push sp ; ax != sp if (8086/88/186/V20/30/...) pop ax ; ax == sp if (80286 or 80386) cmp ax,sp ; je not_86 ; mov ax, 1 ; is 86/88/186 ret ; not_86: ; have 286 or 386 pushf ; determine which via IOPL flags pop ax ; or ah,30h ; set IOPL == 3 push ax ; popf ; pushf ; 386 if (ax == 3xxx) else pop ax ; 286 if (ax == 0xxx ) and ah,30h ; cmp ah,30h ; je is_386 ; ; mov ax, 2 ; is 286 ret ; ; is_386: ; mov ax, 3 ; is 386 ret machine_type: mov ax,0FFFFh ; address top of ROM mov es,ax mov al,es:.0Eh ; get IBM model byte cmp al,0FCh ; AT or PS/2 50/60 jne ckf_30 ; mov ax, 1 ; is AT or PS/2 50 or 60 chf_30: cmp al,0FAh ; jne ckf_80 ; mov ax, 2 ; is PS/2 model 30 ret ckf_80: cmp al,0F8h ; jne no_mt ; mov ax, 2 ; is PS/2 model 80 ret ; no_mt: ; mov ax, 0 ; none of the above ret ; John L. Connin (peora!rtmvax!johnc)
chasm@killer.DALLAS.TX.US (Charles Marslett) (01/30/89)
In article <2880@rtmvax.UUCP>, johnc@rtmvax.UUCP (John Connin) writes: > First, as a policy, I believe that Minix should NOT rely on BIOS services. > Yes, I know it makes life easier, but my feeling is that doing so detracts > from the beauty of Minix. The beauty of MINIX is not in running directly over the hardware (that is the beauty of SCO Xenix, Microport Unix, Interactive Unix, etc.) -- MINIX is small enough to be understandable and still not a career, MINIX is large enough to be useful, and MINIX runs on the computer I own. To keep the other two characteristics, MINIX will need to take full advantage of any help the BIOS provides if it is to run on a reasonable number of (non-IBM) computers and especially if it is to avoid being rewritten every time a new computer box is released. The BIOS was written to provide a cushion against the future changes of the hardware, and if it is not performing that function perfectly, think how hard it would be to do anything without it. MINIX probably has 10K of vendor specific code in it now (for PS/2s, ATs, XTs, etc.) and if it had to boot without the BIOS we would have 10 to 50 incompatible binarys instead of 3 (or 2?, STs, ATs and XTs). > As to AST's question, though not comprehensive, perhaps the follow code > fragments will help. One determines the processor type by executing selected > instructions. The other determines the machine type by testing the > 'model byte' located at 0xFFFF:000E. Perhaps someone more knowledgeable > than myself can contribute a comprehensive model byte list. The model byte is almost useless as a processor type detector, since the various clone BIOS writers have to stuff a value that works best with the available (MSDOS) software -- V20/V30 based systems often call themselves ATs (without extended memory), PS/2 boxes have a whole new set of ID bytes, since they are all the same, but different, and most clone AT and 386 boxes use either Compaq's code or the IBM AT codes . . . I have found that the model byte is most useful to tell if there are 1 or 2 interrupt controllers (since lots of MSDOS software uses it for this purpose), but it tells you very little else unless you are willing to limit your universe to the high priced boxes. > An additional piece of information (clone type) can be had by checking > the BIOS 'id_string' at 0xF000:0xFFEA (eg. "IBM", "COMPAQ", "OLIVETTI",..). Again, only if you are willing to ignore "cheap" clones. For example, most Phoenix BIOSes have no useful string there at all. > As an addition thought, I believe it would be prudent to collect all > low level "survey code" into one code module. As envisioned, this code > would be called by kernel/main and would place results in a "system data" > structure which is accessable to all other OS modules. I agree on this point, the code will have to be modified (even using all the help we can get from any source whatsoever) fairly often, and it will be the most likely candidate for any failure to boot on a new computer. Localizing it makes the task of maintaining it all that much easier. > John L. Connin (peora!rtmvax!johnc) =========================================================================== Charles Marslett STB Systems, Inc. <== Apply all standard disclaimers Wordmark Systems <== No disclaimers required -- that's just me chasm@killer.dallas.tx.us