File: kfreebsd.diff

package info (click to toggle)
grub 0.97-27etch1
  • links: PTS
  • area: main
  • in suites: etch
  • size: 4,576 kB
  • ctags: 8,866
  • sloc: ansic: 38,787; sh: 5,559; asm: 2,014; makefile: 652; perl: 338
file content (362 lines) | stat: -rw-r--r-- 9,507 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

  Enable kFreeBSD support in GRUB, by Guillem Jover <guillem@debian.org>

  Warning:  This feature is undocumented because it's highly experimental.
  If you don't know how to use it, you better don't!

diff -ur grub-0.95+cvs20040624.old/stage2/boot.c grub-0.95+cvs20040624/stage2/boot.c
--- grub-0.95+cvs20040624.old/stage2/boot.c	2004-03-29 16:54:30.000000000 +0200
+++ grub-0.95+cvs20040624/stage2/boot.c	2004-06-26 03:46:45.000000000 +0200
@@ -29,6 +29,8 @@
 entry_func entry_addr;
 static struct mod_list mll[99];
 static int linux_mem_size;
+static int elf_kernel_addr;
+static int elf_kernel_size;
 
 /*
  *  The next two functions, 'load_image' and 'load_module', are the building
@@ -594,6 +596,7 @@
 
       /* reset this to zero for now */
       cur_addr = 0;
+      elf_kernel_addr = ~0;
 
       /* scan for program segments */
       for (i = 0; i < pu.elf->e_phnum; i++)
@@ -630,6 +633,8 @@
 	      /* mark memory as used */
 	      if (cur_addr < memaddr + memsiz)
 		cur_addr = memaddr + memsiz;
+	      if (elf_kernel_addr > cur_addr)
+		elf_kernel_addr = cur_addr;
 	      printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz,
 		      memsiz - filesiz);
 	      /* increment number of segments */
@@ -647,6 +652,8 @@
 	    }
 	}
 
+      elf_kernel_size = cur_addr - elf_kernel_addr;
+
       if (! errnum)
 	{
 	  if (! loaded)
@@ -864,6 +871,129 @@
 }
 #endif
 
+#define mem_align4k(p)	((p) + 0xFFF) & 0xFFFFF000
+
+static void
+kfreebsd_setenv (char *env, const char *var, const char *value)
+{
+  while (1)
+    {
+      if (env[0] == '\0' && env[1] == '\0')
+	{
+	  env++;
+	  break;
+	}
+      else
+        env++;
+    }
+
+  grub_sprintf (env, "%s=%s", var, value);
+  env[grub_strlen (env) + 1] = '\0';
+}
+
+static char *
+kfreebsd_read_hints (char *buf)
+{
+  char *buf_end = buf;
+
+  if (grub_open ("/boot/device.hints"))
+    {
+      char *line_start;
+      int line_len = 0;
+      char *envp;
+      int env_len;
+
+      env_len = grub_read (buf, -1);
+      if (env_len)
+	{
+	  buf_end += env_len;
+	  *(buf_end++) = '\0';
+	}
+      else
+	return buf_end;
+
+      grub_close ();
+
+      envp = line_start = buf;
+      while (*envp)
+	{
+	  char *envp_current = envp;
+	
+	  switch (*envp)
+	    {
+	      case ' ':
+		while (*envp == ' ')
+		  {
+		    envp++;
+		    env_len--;
+		  }
+		grub_memmove (envp_current, envp, env_len + 1);
+		envp = envp_current;
+		break;
+	      case '#':
+		while (*envp != '\n')
+		  {
+		    envp++;
+		    env_len--;
+		  }
+		if (!line_len)
+		  envp++;
+		grub_memmove (envp_current, envp, env_len + 1);
+		envp = envp_current;
+		break;
+	      case '\n':
+		if (!line_len)
+		  {
+		    env_len--;
+		    grub_memmove (line_start, envp, env_len + 1);
+		  }
+		*(envp++) = '\0';
+		line_len = 0;
+		line_start = envp;
+	      default:
+		envp++;
+		line_len++;
+		break;
+	    }
+	}
+
+      buf_end = buf + env_len;
+      *(buf_end++) = '\0';
+    }
+
+  return buf_end;
+}
+
+static u32_t *
+kfreebsd_set_module_string (u32_t type, u32_t *dst, char *src)
+{
+  int size;
+
+  *(dst++) = type;
+  *(dst++) = size = grub_strlen (src) + 1;
+  grub_strcpy ((void *) dst, src);
+
+  return dst + (size + sizeof(u32_t) - 1) / sizeof(u32_t);
+}
+
+static u32_t *
+kfreebsd_set_module_var (u32_t type, u32_t *dst, u32_t src)
+{
+  *(dst++) = type;
+  *(dst++) = sizeof(u32_t);
+  *(dst++) = src;
+
+  return dst;
+}
+
+static u32_t *
+kfreebsd_set_modules (u32_t *modulep)
+{
+  /* XXX: Need to copy the whole module structure.  */
+  /* XXX: How to pass the module name ?  */
+
+  return modulep;
+}
 
 /*
  *  All "*_boot" commands depend on the images being loaded into memory
@@ -877,7 +1007,10 @@
 bsd_boot (kernel_t type, int bootdev, char *arg)
 {
   char *str;
-  int clval = 0, i;
+  char *kernelname;
+  char *bsd_root;
+  int clval = 0;
+  int i;
   struct bootinfo bi;
 
 #ifdef GRUB_UTIL
@@ -886,8 +1019,21 @@
   stop_floppy ();
 #endif
 
+  while (*arg != '/')
+    arg++;
+  kernelname = arg;
+
   while (*(++arg) && *arg != ' ');
+  *(arg++) = 0;
   str = arg;
+
+  bsd_root = grub_strstr (str, "root=");
+  if (bsd_root)
+    {
+      bsd_root += 5;
+      /* XXX: should copy the str or terminate it.  */
+    }
+
   while (*str)
     {
       if (*str == '-')
@@ -910,6 +1056,8 @@
 		clval |= RB_GDB;
 	      if (*str == 'h')
 		clval |= RB_SERIAL;
+	      if (*str == 'p')
+		clval |= RB_PAUSE;
 	      if (*str == 'm')
 		clval |= RB_MUTE;
 	      if (*str == 'r')
@@ -927,14 +1075,17 @@
 
   if (type == KERNEL_TYPE_FREEBSD)
     {
+      char *envp;
+      u32_t *modp;
+
       clval |= RB_BOOTINFO;
 
       bi.bi_version = BOOTINFO_VERSION;
 
-      *arg = 0;
-      while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/');
-      if (*arg == '/')
-	bi.bi_kernelname = arg + 1;
+      bi.bi_pad[0] = bi.bi_pad[1] = 0;
+
+      if (*kernelname == '/')
+	bi.bi_kernelname = kernelname;
       else
 	bi.bi_kernelname = 0;
 
@@ -961,6 +1112,30 @@
       bi.bi_basemem = mbi.mem_lower;
       bi.bi_extmem = extended_memory;
 
+      /* Setup the environment.  */
+      bi.bi_envp = cur_addr = mem_align4k (cur_addr);
+      grub_memset ((void *) cur_addr, 0, 2);
+      cur_addr = (int) kfreebsd_read_hints ((void *) cur_addr);
+
+      envp = (char *) bi.bi_envp;
+      kfreebsd_setenv (envp, "kernelname", kernelname);
+      kfreebsd_setenv (envp, "vfs.root.mountfrom", bsd_root);
+
+      /* Setup the modules list.  */
+      bi.bi_modulep = cur_addr = mem_align4k (cur_addr);
+      modp = (u32_t *) bi.bi_modulep;
+      /* The first module is the kernel.  */
+      modp = kfreebsd_set_module_string (MODINFO_NAME, modp, kernelname);
+      modp = kfreebsd_set_module_string (MODINFO_TYPE, modp, "elf kernel");
+      modp = kfreebsd_set_module_string (MODINFO_ARGS, modp, arg);
+      modp = kfreebsd_set_module_var (MODINFO_ADDR, modp, elf_kernel_addr);
+      modp = kfreebsd_set_module_var (MODINFO_SIZE, modp, elf_kernel_size);
+      /* Now the real modules.  */
+      modp = kfreebsd_set_modules(modp);
+
+      /* Set the kernel end.  */
+      bi.bi_kernend = cur_addr = mem_align4k (((int) modp) + 1);
+
       if (mbi.flags & MB_INFO_AOUT_SYMS)
 	{
 	  bi.bi_symtab = mbi.syms.a.addr;
@@ -970,8 +1145,9 @@
 #if 0
       else if (mbi.flags & MB_INFO_ELF_SHDR)
 	{
-	  /* FIXME: Should check if a symbol table exists and, if exists,
-	     pass the table to BI.  */
+	  bi.bi_symtab = mbi.syms.e.addr;
+	  bi.bi_esymtab = mbi.syms.e.addr
+	    + mbi.syms.e.size * mbi.syms.e.num * mbi.syms.e.shndx;
 	}
 #endif
       else
diff -ur grub-0.95+cvs20040624.old/stage2/freebsd.h grub-0.95+cvs20040624/stage2/freebsd.h
--- grub-0.95+cvs20040624.old/stage2/freebsd.h	2002-11-30 18:33:06.000000000 +0100
+++ grub-0.95+cvs20040624/stage2/freebsd.h	2004-06-26 03:46:45.000000000 +0200
@@ -1,7 +1,7 @@
 
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2001  Free Software Foundation, Inc.
+ *  Copyright (C) 2001, 2004  Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -35,6 +35,10 @@
 #define RB_CDROM        0x2000	/* use cdrom as root */
 #define RB_GDB		0x8000	/* use GDB remote debugger instead of DDB */
 #define RB_MUTE		0x10000	/* Come up with the console muted */
+#define RB_SELFTEST	0x20000 /* don't complete the boot; do selftest */
+#define RB_RESERVED1	0x40000 /* reserved for internal use of boot blocks */
+#define RB_RESERVED2	0x80000 /* reserved for internal use of boot blocks */
+#define RB_PAUSE	0x100000 /* pause after each output line during probe */
 #define RB_MULTIPLE	0x20000000	/* Use multiple consoles */
 
 #define RB_BOOTINFO     0x80000000	/* have `struct bootinfo *' arg */
@@ -70,6 +74,9 @@
 
 #define N_BIOS_GEOM             8
 
+typedef unsigned char u8_t;
+typedef unsigned int u32_t;
+
 /*
  * A zero bootinfo field often means that there is no info available.
  * Flags are used to indicate the validity of fields where zero is a
@@ -77,19 +84,33 @@
  */
 struct bootinfo
   {
-    unsigned int bi_version;
-    unsigned char *bi_kernelname;
-    struct nfs_diskless *bi_nfs_diskless;
+    u32_t bi_version;
+    u8_t *bi_kernelname;
+    u32_t bi_nfs_diskless;
     /* End of fields that are always present. */
 #define bi_endcommon            bi_n_bios_used
-    unsigned int bi_n_bios_used;
-    unsigned long bi_bios_geom[N_BIOS_GEOM];
-    unsigned int bi_size;
-    unsigned char bi_memsizes_valid;
-    unsigned char bi_bios_dev;
-    unsigned char bi_pad[2];
-    unsigned long bi_basemem;
-    unsigned long bi_extmem;
-    unsigned long bi_symtab;
-    unsigned long bi_esymtab;
+    u32_t bi_n_bios_used;
+    u32_t bi_bios_geom[N_BIOS_GEOM];
+    u32_t bi_size;
+    u8_t bi_memsizes_valid;
+    u8_t bi_bios_dev;
+    u8_t bi_pad[2];
+    u32_t bi_basemem;
+    u32_t bi_extmem;
+    u32_t bi_symtab;
+    u32_t bi_esymtab;
+    /* Items below only from advanced bootloader */
+    u32_t bi_kernend;
+    u32_t bi_envp;
+    u32_t bi_modulep;
   };
+
+#define MODINFO_END		0x0000		/* End of list */
+#define MODINFO_NAME		0x0001		/* Name of module (string) */
+#define MODINFO_TYPE		0x0002		/* Type of module (string) */
+#define MODINFO_ADDR		0x0003		/* Loaded address */
+#define MODINFO_SIZE		0x0004		/* Size of module */
+#define MODINFO_EMPTY		0x0005		/* Has been deleted */
+#define MODINFO_ARGS		0x0006		/* Parameters string */
+#define MODINFO_METADATA	0x8000		/* Module-specfic */
+