hgm@beta.UUCP (Harry McGavran) (07/13/87)
I am posting this response to Eric Roskos, uw-beaver!tikal!amc!ipmoea!ericr, because the troubles he is having with developing a MSC environment for MINIX I have seen before, and thought my experience might be helpful to others as well. Eric writes: >1) What are the "absread" and "abswrite" functions that are used in build.c >to write the boot disk out under DOS? I had assumed that they were just >simple calls to the DOS absolute disk I/O routines, (not the BIOS, the DOS >ones), but after finding it didn't work and doing several days of debugging >on it, I've reached the conclusion that these apparently write the disk >sectors out in a different physical sequence than the Minix boot code tries >to read in. ............ The "absread" and "abswrite" I assumed were to be used in build were to be scarfed from diskio.asm. Those routines simply failed under DOS, but INT 25 and INT 26 are known to have subtle effects, something I had suffered through a long time ago. I wrote a couple absolute disk io routines myself to avoid having to remember what the subtle problems were every time, so I just switched to those. The calling sequence was different so I changed the build source to conform to my library, rather than the other way around, since I used these routines in lots of places in my other codes. It also meant changing the code for the error handling from these routines in build as well. Code replaced in build: ------------------------------- read_block (blocknr,user) int blocknr; char user[SECTOR_SIZE]; { /* read the requested MINIX-block in core */ int retries,err,i; char *p; unsigned int flags; retries = MAX_RETRIES; do err = abs_read(drive, 1, blocknr, buff, &flags) & 1; while (err && --retries); if (!retries) dexit ("reading",drive,blocknr,flags); p=buff; i=SECTOR_SIZE; while (i--) *(user++) = *(p++); } write_block (blocknr,user) int blocknr; char user[SECTOR_SIZE]; { /* write the requested MINIX-block to disk */ int retries,err,i; char *p; unsigned int flags; p=buff; i=SECTOR_SIZE; while (i--) *(p++) = *(user++); retries = MAX_RETRIES; do err = abs_write(drive, 1, blocknr, buff, &flags) & 1; while (err && --retries); if (!retries) dexit ("writing",drive,blocknr,flags); } dexit (s,drive,sectnum,err) int sectnum, err,drive; char *s; { extern char *derrtab[]; printf ("Error %s drive %c, sector: %d, code: 0x%x, %s\n", s, drive+'A',sectnum, err, derrtab[(err&0xff)+1] ); exit (2); } ------------------------------ That fixed the problem. Routines follow. (The include file specified the memory model, you can figure out for yourself what it contains, it just handles the offsets for the argument lists automatically. As I recall, for MINIX, just setting off EQU 02H, should be sufficient for model.h) I had to edit these sources in from another location, so hopefully I didn't make any errors. I checked a couple times and it looks ok, but to be safe you should check for yourself. The code is pretty simple and fairly well commented. absread replacement: ----------------------------- name abs_read include model.h ;do an absolute disk read ;ds:bx will contain the data read ;carry_flag = abs_read(drive, #_sec_2_read, start_sec, buffer, ret_flags); if @large_code abs_read_TEXT segment byte public 'CODE' assume cs:abs_read_TEXT, ds:nothing else _TEXT segment byte public 'CODE' assume cs:_TEXT, ds:nothing endif public _abs_read if @large_code _ abs_read proc far else _ abs_read proc near endif start: push bp mov bp,sp push di push si push es if @large_data push ds ;save ds endif push bp ;save bp, int 25 destroys it mov ax,[bp + @off + 00H] ;drive number mov cx,[bp + @off + 02H] ;number of sectors mov dx,[bp + @off + 04H] ;beginning sector number mov bx,[bp + @off + 06H] ;transfer area offset address if @large_data mov ds,[bp + @off + 08H] ;transfer area segment address endif int 25H ;absolute disk read pushf ;put carry flag in ax pop ax; ;return value pop cx ;int 25 pushes return flags ;save them pop bp ;restore bp if @large_data mov bx,[bp + @off + 0AH] ;offset of flag mov ds,[bp + @off + 0CH] ;segment of flag else mov bx,[bp + @off + 08H] ;offset of flag ;segment in small model is constant endif mov [bx],cx ;return flags done: ;restore registers if @large_data pop ds endif pop es pop si pop di mov sp,bp pop bp ret _ abs_read endp if @large_code abs_read_TEXT ends else _TEXT ends endif end ---------------------- abswrite replacement: ----------------------------- name abs_write include model.h ;do an absolute disk write ;ds:bx constains the data to write ;carry_flag = abs_write(drive, #_sec_2_read, start_sec, buffer, ret_flags); if @large_code abs_writ_TEXT segment byte public 'CODE' assume cs:abs_writ_TEXT, ds:nothing else _TEXT segment byte public 'CODE' assume cs:_TEXT, ds:nothing endif public _abs_write if @large_code _abs_write proc far else _abs_write proc near endif start: push bp mov bp,sp push di push si push es if @large_data push ds ;save ds endif push bp ;save bp, int 25 destroys it mov ax,[bp + @off + 00H] ;drive number mov cx,[bp + @off + 02H] ;number of sectors mov dx,[bp + @off + 04H] ;beginning sector number mov bx,[bp + @off + 06H] ;transfer area offset address if @large_data mov ds,[bp + @off + 08H] ;transfer area segment address endif int 26H ;absolute disk write pushf ;put carry flag in ax pop ax; ;return value pop cx ;int 26 pushes return flags ;save them pop bp ;restore bp if @large_data mov bx,[bp + @off + 0AH] ;offset of flag mov ds,[bp + @off + 0CH] ;segment of flag else mov bx,[bp + @off + 08H] ;offset of flag ;segment in small model is constant endif mov [bx],cx ;return flags done: ;restore registers if @large_data pop ds endif pop es pop si pop di mov sp,bp pop bp ret _abs_write endp if @large_code abs_writ_TEXT ends else _TEXT ends endif end -------------------------------- Eric writes: >In the routine mm_init() in the file main.c in mm, on line 5517 in the >textbook, mm_init calls a routine called get_tot_mem(). I can't figure out >where this routine is in the source files! It's not in the cross reference >at the end of the book, and I've been unsuccessful in searching for it with >grep. Can anyone tell me where it is? 2) Finding get_tot_mem was a problem for me too. It turns out that it is supposed to be in getutil.asm in the library, BUT, in so much of the junk under C86, the names were truncated. I had to go through all the library, kernel, etc. stuff, extend the names and prepend "_" for MSC. There are suggestions in the cross development stuff that you just start with PC-IX instead, (or the MINIX assembly source) I eventually found it was easier to translate that back into MASM, than to use the C86 junk. There are also errors in the C86 stuff in other places as well. Look in getutil.s under PC-IX or MINIX. As usual, I make no statements as to the suitability of these suggestions for anything. Hopefully, those interested in using MSC will find them at least entertaining. MSC works well for me for MINIX. Harry McGavran Group C-8 Los Alamos National Laboratory ARPA: hgm@lanl.GOV USENET: ihnp4!lanl!hgm cmcl2!lanl!hgm