rev |
line source |
pascal@17446
|
1 --- LINLD097/LOAD.CPP
|
pascal@17446
|
2 +++ LINLD097/LOAD.CPP
|
pascal@19465
|
3 @@ -10,12 +10,21 @@
|
pascal@19465
|
4 if(cnt != size) die(msg);
|
pascal@19465
|
5 }
|
pascal@19465
|
6
|
pascal@19465
|
7 -static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
|
pascal@19465
|
8 - int fd = open(fn, O_RDONLY|O_BINARY);
|
pascal@19465
|
9 - if(fd == -1) die(msg);
|
pascal@19465
|
10 - u32 size = lseek(fd,0,SEEK_END);
|
pascal@19465
|
11 - if(s32(size)==-1L) die(msg);
|
pascal@19465
|
12 +static int openimage(const char *name, const char *failmsg, u32 *size) {
|
pascal@19465
|
13 + int fd = open(name, O_RDONLY|O_BINARY);
|
pascal@19465
|
14 + if(fd != -1) {
|
pascal@19465
|
15 + *size = lseek(fd,0,SEEK_END);
|
pascal@19465
|
16 + if(s32(*size)!=-1L) goto gotimage;
|
pascal@19465
|
17 + }
|
pascal@19465
|
18 + die(failmsg);
|
pascal@19465
|
19 + gotimage:
|
pascal@19465
|
20 lseek(fd,0,SEEK_SET);
|
pascal@19465
|
21 + return fd;
|
pascal@19465
|
22 +}
|
pascal@19465
|
23 +
|
pascal@19465
|
24 +static char* read_cmdline_or_die(const char* fn, u16 maxsz, const char* msg) {
|
pascal@19465
|
25 + u32 size;
|
pascal@19465
|
26 + int fd = openimage(fn, msg, &size);
|
pascal@19465
|
27 if(size>=maxsz) die(msg);
|
pascal@19465
|
28 char *buf = malloc_or_die(size+1, msg); // +1 for '\0'
|
pascal@19465
|
29 read_or_die(fd, buf, size, msg);
|
pascal@19465
|
30 @@ -188,7 +197,7 @@
|
pascal@19465
|
31 u8 pad30[0x400-0x22c]; // 022C
|
pascal@19465
|
32 // 02D0 up to 32 20-byte mem info structs from
|
pascal@19465
|
33 // int 0x15 fn 0xe820
|
pascal@19465
|
34 -}; //__attribute((packed));
|
pascal@19465
|
35 +} *first1k; //__attribute((packed));
|
pascal@19465
|
36
|
pascal@19465
|
37 #if sizeof(first1k_t)!=0x400
|
pascal@19465
|
38 #error BUG: Bad first1k
|
pascal@19465
|
39 @@ -219,7 +228,7 @@
|
pascal@19465
|
40
|
pascal@19465
|
41 // Called from inside kernel just before rm->pm
|
pascal@19465
|
42 // _loadds _saveregs: done by hand
|
pascal@19465
|
43 -static void far last_ditch() {
|
pascal@19465
|
44 +void far last_ditch() {
|
pascal@19465
|
45 cli(); // we start doing *really* destructive things to DOS/BIOS
|
pascal@19465
|
46 // it means: do not even try to enable ints
|
pascal@19465
|
47 // or call BIOS services after this
|
pascal@19465
|
48 @@ -296,6 +305,11 @@
|
pascal@19465
|
49 "\tvga=0" NL
|
pascal@19465
|
50 "Use quotes: \"cl=...\" if you need spaces in cmdline" NL
|
pascal@19465
|
51 "Use cl=@filename to take cmdline from file"
|
pascal@19465
|
52 +#if 0
|
pascal@19465
|
53 + NL NL "Example" NL
|
pascal@19465
|
54 + "\tcopy/b rootfs4.gz+rootfs3.gz+rootfs2.gz+rootfs1.gz rootfs.gz" NL
|
pascal@19465
|
55 + "\tlinld initrd=rootfs.gz \"cl=rw root=/dev/null video=-32\""
|
pascal@19465
|
56 +#endif
|
pascal@19465
|
57 );
|
pascal@19465
|
58 }
|
pascal@19465
|
59
|
pascal@19465
|
60 @@ -331,7 +345,10 @@
|
pascal@19465
|
61
|
pascal@19465
|
62 // Parse command line
|
pascal@19465
|
63
|
pascal@19465
|
64 - if(argc<2) syntax();
|
pascal@19465
|
65 + if(argc<2) {
|
pascal@19465
|
66 +dosyntax:
|
pascal@19465
|
67 + syntax();
|
pascal@19465
|
68 + }
|
pascal@19465
|
69 #define STRNCMP(a,b) strncmp((a),(b),sizeof(b)-1)
|
pascal@19465
|
70 {for(int i=1;i<argc;i++) {
|
pascal@19465
|
71 if(STRNCMP(argv[i],"image=") == 0) {
|
pascal@19465
|
72 @@ -340,28 +357,23 @@
|
pascal@19465
|
73 else if(STRNCMP(argv[i],"initrd=") == 0) {
|
pascal@19465
|
74 initrd_name=argv[i]+7;
|
pascal@19465
|
75 }
|
pascal@19465
|
76 - else if(STRNCMP(argv[i],"cl=@") == 0) {
|
pascal@19465
|
77 - cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
|
pascal@19465
|
78 - puts("Kernel command line:");
|
pascal@19465
|
79 - puts(cmdline);
|
pascal@19465
|
80 - }
|
pascal@19465
|
81 else if(STRNCMP(argv[i],"cl=") == 0) {
|
pascal@19465
|
82 cmdline=argv[i]+3;
|
pascal@19465
|
83 + if (cmdline[0] == '@') {
|
pascal@19465
|
84 + cmdline=read_cmdline_or_die(argv[i]+4,PAGE_SIZE-1,"Error reading cl=@file");
|
pascal@19465
|
85 + puts("Kernel command line:");
|
pascal@19465
|
86 + puts(cmdline);
|
pascal@19465
|
87 + }
|
pascal@19465
|
88 }
|
pascal@19465
|
89 - else if(strcmp(argv[i],"vga=ask") == 0) {
|
pascal@19465
|
90 - vid_mode = -3;
|
pascal@19465
|
91 - }
|
pascal@19465
|
92 - else if(strcmp(argv[i],"vga=extended") == 0) {
|
pascal@19465
|
93 - vid_mode = -2;
|
pascal@19465
|
94 - }
|
pascal@19465
|
95 - else if(strcmp(argv[i],"vga=normal") == 0) {
|
pascal@19465
|
96 - vid_mode = -1;
|
pascal@19465
|
97 - }
|
pascal@19465
|
98 else if(STRNCMP(argv[i],"vga=") == 0) {
|
pascal@19465
|
99 - vid_mode = strtoul(argv[i]+4);
|
pascal@19465
|
100 + const char *s=argv[i]+4;
|
pascal@19465
|
101 + if (*s == 'a') vid_mode = -3;
|
pascal@19465
|
102 + else if (*s == 'e') vid_mode = -2;
|
pascal@19465
|
103 + else if (*s == 'n') vid_mode = -1;
|
pascal@19465
|
104 + else vid_mode = strtoul(s);
|
pascal@19465
|
105 }
|
pascal@19465
|
106 else
|
pascal@19465
|
107 - syntax();
|
pascal@19465
|
108 + goto dosyntax;
|
pascal@19465
|
109 }}
|
pascal@19465
|
110 #undef STRNCMP
|
pascal@19465
|
111
|
pascal@19465
|
112 @@ -384,15 +396,12 @@
|
pascal@19465
|
113
|
pascal@19465
|
114 rm_buf = malloc_or_die(_32k, "Can't allocate rm buf");
|
pascal@19465
|
115 // Do not use malloc below until heap_top adjustment (see <*>)
|
pascal@19465
|
116 - int fd = open(kernel_name, O_RDONLY|O_BINARY);
|
pascal@19465
|
117 - if(fd == -1) die("Can't open kernel file");
|
pascal@19465
|
118 - u32 image_size = lseek(fd,0,SEEK_END);
|
pascal@19465
|
119 - if(s32(image_size)==-1L) die("Can't seek kernel file");
|
pascal@19465
|
120 - lseek(fd,0,SEEK_SET);
|
pascal@19465
|
121 + u32 image_size;
|
pascal@19465
|
122 + int fd = openimage(kernel_name, "Can't use kernel file", &image_size);
|
pascal@19465
|
123 read_or_die(fd, rm_buf, 0x400, "Can't read first kb");
|
pascal@19465
|
124
|
pascal@19465
|
125 - struct first1k_t* first1k = (first1k_t*)rm_buf;
|
pascal@19465
|
126 - // new kernels never need: if(!first1k->setup_sects) first1k->setup_sects=4;
|
pascal@19465
|
127 + first1k = (first1k_t*)rm_buf;
|
pascal@19465
|
128 + if(!first1k->setup_sects) first1k->setup_sects=4;
|
pascal@19465
|
129 rm_size = 0x200*(first1k->setup_sects+1); // 0th sector is not counted there
|
pascal@19465
|
130 if(rm_size>_32k)
|
pascal@19465
|
131 die("rm_size is too big");
|
pascal@19465
|
132 @@ -400,33 +409,46 @@
|
pascal@17446
|
133
|
pascal@17446
|
134 if(first1k->boot_flag != 0xAA55)
|
pascal@17446
|
135 die("No boot signature (55,AA). It's not a kernel");
|
pascal@17446
|
136 - if(first1k->header != HdrS)
|
pascal@18228
|
137 - die("No 'HdrS' signature (kernel is too old)");
|
pascal@17446
|
138 - if(first1k->version < 0x202)
|
pascal@17446
|
139 - die("Loader protocol version is less than 2.02 (kernel is too old)");
|
pascal@19465
|
140 - if(!(first1k->loadflags & 0x01))
|
pascal@19465
|
141 - die("I can't load bzImages low");
|
pascal@17446
|
142
|
pascal@19465
|
143 - // Read remaining rm loader
|
pascal@19465
|
144 -
|
pascal@19465
|
145 - read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
|
pascal@19465
|
146 -
|
pascal@17446
|
147 // Tell rm loader some info
|
pascal@17446
|
148
|
pascal@17446
|
149 first1k->vid_mode = vid_mode;
|
pascal@17446
|
150 - first1k->cmd_line_ptr = 0x98000;
|
pascal@19465
|
151 - first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
|
pascal@19465
|
152 - // * will be called just before rm -> pm
|
pascal@19465
|
153 - first1k->realmode_switch_ofs = ofs(last_ditch);
|
pascal@19465
|
154 - first1k->realmode_switch_seg = seg(last_ditch);
|
pascal@19204
|
155 - // * offset limit of the setup heap
|
pascal@19204
|
156 - // heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
|
pascal@19204
|
157 - first1k->heap_end_ptr = _32k-0x0200;
|
pascal@19204
|
158 - first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
|
pascal@19465
|
159 - // * if we will ever stop moving ourself to 0x90000
|
pascal@19465
|
160 - // we must say setup.S how much to move
|
pascal@19465
|
161 - //first1k->setup_move_size = _32k;
|
pascal@19465
|
162 +#if 1
|
pascal@19465
|
163 + if(first1k->header == HdrS) { // starting linux 1.3.73
|
pascal@19465
|
164 + if(first1k->loadflags & 1) {
|
pascal@19465
|
165 +#else
|
pascal@19465
|
166 + if((first1k->header != HdrS) || (first1k->loadflags & 1) == 0)
|
pascal@19465
|
167 + die("I can't load bzImage low");
|
pascal@19465
|
168 + {
|
pascal@19465
|
169 + {
|
pascal@19465
|
170 +#endif
|
pascal@19465
|
171 + first1k->realmode_switch_ofs = ofs(last_ditch);
|
pascal@19465
|
172 + first1k->realmode_switch_seg = seg(last_ditch);
|
pascal@19465
|
173 + }
|
pascal@19465
|
174 + first1k->type_of_loader = 0xff; // kernel do not know us (yet :-)
|
pascal@19465
|
175 + // * will be called just before rm -> pm
|
pascal@19465
|
176 + if(first1k->version >= 0x201) {
|
pascal@19465
|
177 + // * offset limit of the setup heap
|
pascal@19465
|
178 + // heap_end_ptr appears to be relative to the start of setup (ofs 0x0200)
|
pascal@19465
|
179 + first1k->heap_end_ptr = _32k-0x0200;
|
pascal@19465
|
180 + first1k->loadflags |= 0x80; // says to rm loader it's ok to use heap
|
pascal@19465
|
181 + }
|
pascal@19465
|
182 + // * if we will ever stop moving ourself to 0x90000
|
pascal@19465
|
183 + // we must say setup.S how much to move
|
pascal@19465
|
184 + //first1k->setup_move_size = _32k;
|
pascal@19465
|
185 + if(first1k->version >= 0x202) { // starting linux 2.4.0-test3-pre3
|
pascal@19465
|
186 + first1k->cmd_line_ptr = 0x98000;
|
pascal@19465
|
187 + goto cmd_line_ok;
|
pascal@19465
|
188 + }
|
pascal@19204
|
189 + }
|
pascal@19465
|
190 + first1k->cl_magic = 0xA33F;
|
pascal@19465
|
191 + first1k->cl_ofs = 0x8000;
|
pascal@19465
|
192
|
pascal@19465
|
193 +cmd_line_ok:
|
pascal@19465
|
194 + // Read remaining rm loader
|
pascal@19465
|
195 +
|
pascal@19465
|
196 + read_or_die(fd, rm_buf+0x400, rm_size-0x400, "Can't read rm loader");
|
pascal@19465
|
197 +
|
pascal@19465
|
198 // Read remaining kernel (pm part)
|
pascal@19465
|
199 // Try to load kernel high, maybe even blindly storing it
|
pascal@19465
|
200 // in unallocated memory as a last resort
|
pascal@19465
|
201 @@ -449,11 +471,7 @@
|
pascal@19465
|
202 // Read initrd if needed
|
pascal@19465
|
203
|
pascal@19465
|
204 if(initrd_name) {
|
pascal@19465
|
205 - int fd = open(initrd_name, O_RDONLY|O_BINARY);
|
pascal@19465
|
206 - if(fd == -1) die("Can't open initrd file");
|
pascal@19465
|
207 - initrd_size = lseek(fd,0,SEEK_END);
|
pascal@19465
|
208 - if(s32(initrd_size)==-1L) die("Can't seek initrd file");
|
pascal@19465
|
209 - lseek(fd,0,SEEK_SET);
|
pascal@19465
|
210 + int fd = openimage(initrd_name, "Can't use initrd file", &initrd_size);
|
pascal@19465
|
211 initrd_target_addr = (memtop()-initrd_size) & (~PAGE_MASK);
|
pascal@19465
|
212 //not needed: kernel detects this and drops initrd
|
pascal@19465
|
213 //// assume 2:1 decompression ratio
|
pascal@19465
|
214 @@ -520,9 +538,9 @@
|
pascal@19465
|
215
|
pascal@19465
|
216 // Jump to kernel rm code
|
pascal@19465
|
217 set_sregs_jump_seg_ofs(
|
pascal@19465
|
218 - 0x9000, //sregs
|
pascal@19465
|
219 + 0x9020,0, //cs,ip
|
pascal@19465
|
220 0xA000, //sp
|
pascal@19465
|
221 - 0x9020,0 //cs,ip
|
pascal@19465
|
222 + 0x9000 //sregs
|
pascal@19465
|
223 );
|
pascal@19465
|
224
|
pascal@19465
|
225 // Let compiler be happy
|