wok view linld/stuff/load.u @ rev 20256

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