* added compilers lcc and bcc (linux86)
[mascara-docs.git] / i86 / mtx / mtx / loader.html
blobea4e4b707491b0527053fe34a0c80a775ebae32e
1 <Title>460 Class Notes</Title> <Body bgcolor="#00cccc" text="#000000"><H1>460 Lab Assignment #2</H1><pre>
2 Lab Assignment #2 : loader
3 DUE : Week of Jan 23, 2012
6 A simple extension of the MTX booter is a loader, which loads an a.out file
7 into memory for execution. A loader is an essential (utility) function of an
8 operating system.
10 1. a.out file format:
11 Assume bs.s and bc.c are assembly and C source files. Under BCC,
13 ld86 -s bs.o bc.o /usr/lib/bcc/lic.a
15 generates an a.out file consisting of the following parts.
17 |header|Code|Data|...bss.....|
19 where bss is NOT in a.out but its size is recorded in the header.
21 The 32-byte header is composed of 8 longs.
23 0 0x04100301 //(combined I,D space) or 0x04200301=(separate I,D space)
24 1 0x00000020
25 2 text size // code size
26 3 data size // initialized data size
27 4 bss size // uninitialized data size ==> cleared to 0
28 5 0x00000000
29 6 total memory // ignore this field
30 7 symbolTable size // symbol Table size
32 If a.out has a combined I (Instruction) and D (Data) space, its code segment
33 and data+stack segment are all the same, i.e. CS,DS,and SS must be the same
34 segment during execution. This also means that the entire memory image must
35 be no greater than 64KB. ld86 -i generates a.out with separate I and D
36 spaces, in which case the code segment and data+stack segment will be
37 different, allowing a memory image of 128KB (64KB code segment and 64KB
38 data+stack segment).
40 2. The loader
41 To execute a.out, the loader first reads the file header to determine
43 totalMemorySize = tsize + dsize + bsize + (initial)stack_size
45 where the initial stack_size can be a default value, say 8KB, assuming
46 it can be expanded (if necessary) during execution. If the memory image of
47 a loaded a.out cannot be changed, then a max. default stack_size is usually
48 used. Then the loader allocates the needed memory space by
50 ushort segment = OSmalloc(totalMemorySize);
52 where OSmalloc() is the memroy manager of the OS.
54 Then, the loader loads the |code|data| of a.out into memory (starting at
55 segment) and clears the bss section to 0 (so that all the uninitialized
56 globals start with 0 value). Finally, the OS sends CPU to segment to execute
57 a.out.
59 3. LAB2. Specification:
60 Implement a loader that loads an a.out file to memory and execute it.
62 4. HELP Files:
63 4-1. YOUR MTX booter as in Lab #1. It boots /boot/mtx to the segment 0x1000.
65 4-2. Instead of the real MTX, we shall use a S(Simple)OS generated by the
66 following ts.s and tc.c files.
68 -------------------------------------------------
69 bcc -c tc.c
70 as86 -o ts.o ts.s
71 ld86 -d ts.o tc.o /usr/lib/bcc/lic.a
72 mount /dev/fd0 /fd0
73 cp a.out /fd0/boot/sos (you may name it mtx)
74 umount /fd0
75 -------------------------------------------------
77 (1). ts.s file of SOS:
79 .globl begtext, begdata, begbss ! needed by linker
81 .globl _getc,_putc,_diskr,_setes,_inces,_error ! EXPORT
82 .globl _get_byte,_put_byte, _go ! EXPORT
83 .globl _main,_prints ! IMPORT these
85 .text ! these tell as:
86 begtext: ! text,data,bss segments
87 .data ! are all the same.
88 begdata:
89 .bss
90 begbss:
91 .text
93 start:
94 mov ax,cs ! set segment registers for CPU
95 mov ds,ax ! we know CS=0x1000. Let DS=ES=CS
96 mov es,ax ! ES = CS
97 mov ss,ax ! SS = CS ===> all point at 0x1000
99 mov sp,#0 ! SP = 64KB, at 0x2000
101 call _main ! call main() in C
103 dead: jmp dead
106 !---------------------------------------
107 ! diskr(cyl, head, sector, buf) all count from 0
108 ! 4 6 8 10
109 !---------------------------------------
110 _diskr:
111 push bp
112 mov bp,sp ! bp = stack frame pointer
114 movb dl, #0x00 ! drive 0=FD0
115 movb dh, 6[bp] ! head
116 movb cl, 8[bp] ! sector
117 incb cl ! inc sector by 1 to suit BIOS
118 movb ch, 4[bp] ! cyl
119 mov bx, 10[bp] ! BX=buf ==> memory addr=(ES,BX)
120 mov ax, #0x0202 ! READ 2 sectors to (EX, BX)
122 int 0x13 ! call BIOS to read the block
123 jb _error ! to error if CarryBit is on [read failed]
125 pop bp
128 !------------------------------
129 ! error & reboot
130 !------------------------------
131 _error:
132 mov bx, #bad
133 push bx
134 call _prints
136 int 0x19 ! reboot
138 bad: .asciz "Error!\n\r"
140 !======================== I/O functions =================================
142 !---------------------------------------------
143 ! char getc() function: returns a char
144 !---------------------------------------------
145 _getc:
146 xorb ah,ah ! clear ah
147 int 0x16 ! call BIOS to get a char in AX
148 ret
150 !----------------------------------------------
151 ! void putc(char c) function: print a char
152 !----------------------------------------------
153 _putc:
154 push bp
155 mov bp,sp
157 movb al,4[bp] ! get the char into aL
158 movb ah,#14 ! aH = 14
159 movb bl,#0x0B ! bL = CYAN color
160 int 0x10 ! call BIOS to display the char
162 pop bp
165 _setes: push bp
166 mov bp,sp
168 mov ax,4[bp]
169 mov es,ax
171 pop bp
174 _inces: ! inces() inc ES by 0x40, or 1K
175 mov ax,es
176 add ax,#0x40
177 mov es,ax
180 _go: ! go(segment)
181 push bp
182 mov sp,bp
183 mov ax,4[bp]
184 mov segment,ax
188 ! jmpi 0, segment
190 opcode: .byte 0xEA ! jmpi
191 .word 0 ! offset
192 segment: .word 0 ! segment
195 !*===========================================================================*
196 !* get_byte *
197 !*===========================================================================*
198 ! c = get_byte(segment, offset)
199 _get_byte:
200 push bp ! save bp
201 mov bp,sp ! stack frame pointer
202 push es ! save es
204 mov es,4[bp] ! load es with segment value
205 mov bx,6[bp] ! load bx with offset from segment
206 seg es ! go get the byte
207 movb al,[bx] ! al = byte
208 xorb ah,ah ! ax = byte
210 pop es ! restore es
211 pop bp ! restore bp
212 ret ! return to caller
214 !*===========================================================================*
215 !* put_byte *
216 !*===========================================================================*
217 ! put_byte(char,segment,offset)
218 _put_byte:
219 push bp ! save bp
220 mov bp,sp ! stack frame pointer
221 push es ! save es
222 push bx
224 mov es,6[bp] ! load es with seg value
225 mov bx,8[bp] ! load bx with offset from segment
226 movb al,4[bp] ! load byte in aL
227 seg es ! go put the byte to [ES, BX]
228 movb [bx],al ! there it goes
230 pop bx ! restore bx
231 pop es ! restore es
232 pop bp ! restore bp
233 ret ! return to caller
238 (2). tc.c file of SOS:
240 #include "ext2.h" // EXT2 INODE, DIR struct types
241 #include "io.c" // YOUR printf() with "%c %s %d %x %l\n";
242 #include "loader.c" // YOUR loader.c file
244 char filename[64];
245 ushort segment;
247 main()
249 printf("\nSimple OS running\n");
250 while(1){
251 printf("enter filename to execute : ");
252 gets(filename);
253 segment = 0x2000; // choose a free segment
254 if (load(filename, segment)){
255 printf("jmp to segment %s\n", segment\n");
256 go(segment);
258 else{
259 printf("exec ERROR : file not found\n");
266 (3). The executable file /bin/u1 is generated by
267 --------------------------------------------------
268 bcc -c uc.c
269 as86 -o us.o us.s
270 ld86 -s us.o uc.o /usr/lib/bcc/libc.a
271 mount /dev/fd0 /fd0
272 cp a.out /fd0/bin/u1
273 umount /fd0
274 --------------------------------------------------
276 3-1. us.s file
278 .globl begtext, begdata, begbss ! needed by linker
280 .globl _getc,_putc ! EXPORT
281 .globl _main,_prints ! IMPORT these
283 .text ! these tell as:
284 begtext: ! text,data,bss segments
285 .data ! are all the same.
286 begdata:
287 .bss
288 begbss:
289 .text
291 start:
292 mov ax,cs ! set segment registers for CPU
293 mov ds,ax ! we know CS=segment. Let DS=SS
294 mov es,ax ! ES = CS
295 mov ss,ax ! SS = CS ===> all point at segment
296 mov sp,#0 ! SP = 64KB
298 call _main ! call main() in C
300 gomtx: jmpi 0, 0x1000 ! jmp back to SOS at 0x1000
303 !---------------------------------------------
304 ! char getc() function: returns a char
305 !---------------------------------------------
306 _getc:
307 xorb ah,ah ! clear ah
308 int 0x16 ! call BIOS to get a char in AX
309 ret
311 !----------------------------------------------
312 ! void putc(char c) function: print a char
313 !----------------------------------------------
314 _putc:
315 push bp
316 mov bp,sp
318 movb al,4[bp] ! get the char into aL
319 movb ah,#14 ! aH = 14
320 movb bl,#0x0C ! bL = RED color
321 int 0x10 ! call BIOS to display the char
323 pop bp
327 3-2 uc.c file
329 #include "io.c" // YOUR gets(), printf(), etc.
331 main()
333 char name[64];
334 ushort segment;
336 printf("\nThis is u1 running\n");
337 while(1){
338 printf("what's your name? : ");
339 gets(name);
340 if (strcmp(name, "quit")==0){
341 printf("quit : go back to OS at 0x1000\n");
342 return;
344 printf("Welcome %s\n", name);
349 ===========================================================================
350 In ~samples/LAB2/ sosimage.bin is a diskimage of a bootable sos system.
351 Download and dump it to a floppy disk. Boot up SOS and try to run it.
352 You only need to replace the booter with YOUR booter from Lab#1
353 AND generate YOUR SOS with YOUR loader.c and io.c files.
354 ===========================================================================
355 Programming Tasks:
357 1. Develop your own printf(fmt) function, which can print with
358 fmt = "....%c...%s ...%d ... %x ...%l ...\n"
360 2. Use get_byte()/put_byte() to implement YOUR own
362 ushort get_word(segment, offset) ushort segment, offset;
363 int put_word(word, segment, offset) ushort word,segment,offset;
365 functions in C for read/write a word from/to memory (segment,offset).
368 3. Implement YOUR loader.c
370 load(pathname, segment) char *pathname; ushort segment;
372 1. break up pathname into tokens:
373 /a/b/c/d ==> "a", "b", "c", "d" with n=4
375 2. locate the inode of /a/b/c/d: let ip->INODE of file
376 return 0 if can't find the file
378 3. read file header to get size information;
379 print tsize, dsize, bsize
381 3. load a.out data blocks (with header) into segment.
382 move the executable part (|code|dat|....) upward 32 bytes to
383 eliminate the header.
385 4. Clear bss section (after |code|data|) to 0.
387 5. return 1 for success.