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
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)
25 2 text size // code size
26 3 data size // initialized data size
27 4 bss size // uninitialized data size ==
> cleared to
0
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
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
59 3. LAB2. Specification:
60 Implement a loader that loads an a.out file to memory and execute it.
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 -------------------------------------------------
71 ld86 -d ts.o tc.o /usr/lib/bcc/lic.a
73 cp a.out /fd0/boot/sos (you may name it mtx)
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.
94 mov ax,cs ! set segment registers for CPU
95 mov ds,ax ! we know CS=
0x1000. Let DS=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
106 !---------------------------------------
107 ! diskr(cyl, head, sector, buf) all count from
0
109 !---------------------------------------
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
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]
128 !------------------------------
130 !------------------------------
138 bad: .asciz
"Error!\n\r"
140 !======================== I/O functions =================================
142 !---------------------------------------------
143 ! char getc() function: returns a char
144 !---------------------------------------------
146 xorb ah,ah ! clear ah
147 int
0x16 ! call BIOS to get a char in AX
150 !----------------------------------------------
151 ! void putc(char c) function: print a char
152 !----------------------------------------------
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
174 _inces: ! inces() inc ES by
0x40, or
1K
190 opcode: .byte
0xEA ! jmpi
192 segment: .word
0 ! segment
195 !*===========================================================================*
197 !*===========================================================================*
198 ! c = get_byte(segment, offset)
201 mov bp,sp ! stack frame pointer
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
212 ret ! return to caller
214 !*===========================================================================*
216 !*===========================================================================*
217 ! put_byte(char,segment,offset)
220 mov bp,sp ! stack frame pointer
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
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
249 printf(
"\nSimple OS running\n");
251 printf(
"enter filename to execute : ");
253 segment =
0x2000; // choose a free segment
254 if (load(filename, segment)){
255 printf(
"jmp to segment %s\n", segment\n
");
259 printf("exec ERROR : file not found\n
");
266 (3). The executable file /bin/u1 is generated by
267 --------------------------------------------------
270 ld86 -s us.o uc.o /usr/lib/bcc/libc.a
274 --------------------------------------------------
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.
292 mov ax,cs ! set segment registers for CPU
293 mov ds,ax ! we know CS=segment. Let DS=SS
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 !---------------------------------------------
307 xorb ah,ah ! clear ah
308 int 0x16 ! call BIOS to get a char in AX
311 !----------------------------------------------
312 ! void putc(char c) function: print a char
313 !----------------------------------------------
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
329 #include "io.c
" // YOUR gets(), printf(), etc.
336 printf("\nThis is u1 running\n
");
338 printf("what's your name? :
");
340 if (strcmp(name, "quit
")==0){
341 printf("quit : go back to OS at
0x1000\n
");
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 ===========================================================================
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.