Chameleon

Chameleon Commit Details

Date:2015-04-28 01:11:57 (4 years 2 months ago)
Author:ErmaC
Commit:2661
Parents: 2660
Message:Reworked and order functions for moot.c (Credits to Bronya)
Changes:
M/trunk/i386/boot2/mboot.c

File differences

trunk/i386/boot2/mboot.c
2525
2626
2727
28
28
2929
3030
3131
......
5454
5555
5656
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
8957
9058
9159
......
285253
286254
287255
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
353256
354257
355258
......
445348
446349
447350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
448451
449452
450453
// We don't want it inlined because we specifically want the stack frame
// pointer to be as high as possible and the hi_multiboot function
// copies multiboot_info onto its stack.
uint32_t hi_multiboot(int multiboot_magic, struct multiboot_info *mi_orig);
uint64_t hi_multiboot(int multiboot_magic, struct multiboot_info *mi_orig);
// prototype dochainload for the same reason.
void dochainload();
int multiboot_get_ramdisk_info(int biosdev, struct driveInfo *dip);
static long multiboot_LoadExtraDrivers(FileLoadDrivers_t FileLoadDrivers_p);
// Starts off in the multiboot context 1 MB high but eventually gets into low memory
// and winds up with a bootdevice in eax which is all that boot() wants
// This lets the stack pointer remain very high.
// If we were to call boot directly from multiboot then the whole multiboot_info
// would be on the stack which would possibly be using way too much stack.
void multiboot_to_boot(int multiboot_magic, struct multiboot_info *mi_orig)
{
uint32_t bootdevice = hi_multiboot(multiboot_magic, mi_orig);
if(bootdevice != BAD_BOOT_DEVICE)
{
// boot only returns to do a chain load.
for(;;)
{ // NOTE: boot only uses the last byte (the drive number)
common_boot(bootdevice);
if(chainbootflag)
chainLoad();
else
waitThenReload();
}
}
// Avoid returning to high-memory address which isn't valid in the segment
// we are now in.
// Calling sleep() ensures the user ought to be able to use Ctrl+Alt+Del
// because the BIOS will have interrupts on.
for(;;)
sleep(10);
// NOTE: *IF* we needed to return we'd have to fix up our return address to
// be in low memory using the same trick as below.
// However, there doesn't seem to be any point in returning to assembly
// particularly when the remaining code merely halts the processor.
}
void chainLoad()
{
/* TODO: We ought to load the appropriate partition table, for example
return mi_copy;
}
// When we enter, we're actually 1 MB high.
// Fortunately, memcpy is position independent, and it's all we need
uint32_t hi_multiboot(int multiboot_magic, struct multiboot_info *mi_orig)
{
// Copy the multiboot info out of the way.
// We can't bitch about the magic yet because printf won't work
// because it contains an absolute location of putchar which
// contains absolute locations to other things which eventually
// makes a BIOS call from real mode which of course won't work
// because we're stuck in extended memory at this point.
struct multiboot_info *mi_p = copyMultibootInfo(multiboot_magic, mi_orig);
// Get us in to low memory so we can run everything
// We cannot possibly be more than 447k and copying extra won't really hurt anything
// We use the address of the assembly entrypoint to get our starting location.
memcpy(&boot2_sym, (char*)&boot2_sym + OFFSET_1MEG, BOOT2_MAX_LENGTH /* 447k */);
// This is a little assembler routine that returns to us in the correct selector
// instead of the kernel selector we're running in now and at the correct
// instruction pointer ( current minus 1 MB ). It does not fix our return
// address nor does it fix the return address of our caller.
continue_at_low_address();
// Now fix our return address.
// JrCs: this macro should be rewritten because the code generated by XCode 4.x
// change the value of the argument passed as parameter (multiboot_magic)
// FIX_RETURN_ADDRESS_USING_FIRST_ARG(multiboot_magic);
// We can now do just about anything, including return to our caller correctly.
// However, our caller must fix his return address if he wishes to return to
// his caller and so on and so forth.
/* Zero the BSS and initialize malloc */
initialize_runtime();
gMI = mi_p;
/* Set up a temporary bootArgs so we can call console output routines
like printf that check the v_display. Note that we purposefully
do not initialize anything else at this early stage.
We are reasonably sure we're already in text mode if GRUB booted us.
This is the same assumption that initKernBootStruct makes.
We could check the multiboot info I guess, but why bother?
*/
boot_args temporaryBootArgsData;
bzero(&temporaryBootArgsData, sizeof(boot_args));
bootArgs = &temporaryBootArgsData;
bootArgs->Video.v_display = VGA_TEXT_MODE;
// Install ramdisk and extra driver hooks
p_get_ramdisk_info = &multiboot_get_ramdisk_info;
p_ramdiskReadBytes = &multibootRamdiskReadBytes;
LoadExtraDrivers_p = &multiboot_LoadExtraDrivers;
// Since we call multiboot ourselves, its return address will be correct.
// That is unless it's inlined in which case it does not matter.
uint32_t bootdevice = multiboot(multiboot_magic, mi_p);
// We're about to exit and temporaryBootArgs will no longer be valid
bootArgs = NULL;
return bootdevice;
}
// This is the meat of our implementation. It grabs the boot device from
// the multiboot_info and returns it as is. If it fails it returns
// BAD_BOOT_DEVICE. We can call an awful lot of libsa and libsaio but
return bootdevice;
}
// When we enter, we're actually 1 MB high.
// Fortunately, memcpy is position independent, and it's all we need
uint64_t hi_multiboot(int multiboot_magic, struct multiboot_info *mi_orig)
{
// Copy the multiboot info out of the way.
// We can't bitch about the magic yet because printf won't work
// because it contains an absolute location of putchar which
// contains absolute locations to other things which eventually
// makes a BIOS call from real mode which of course won't work
// because we're stuck in extended memory at this point.
struct multiboot_info *mi_p = copyMultibootInfo(multiboot_magic, mi_orig);
// Get us in to low memory so we can run everything
// We cannot possibly be more than 447k and copying extra won't really hurt anything
// We use the address of the assembly entrypoint to get our starting location.
memcpy(&boot2_sym, (char*)&boot2_sym + OFFSET_1MEG, BOOT2_MAX_LENGTH /* 447k */);
// This is a little assembler routine that returns to us in the correct selector
// instead of the kernel selector we're running in now and at the correct
// instruction pointer ( current minus 1 MB ). It does not fix our return
// address nor does it fix the return address of our caller.
continue_at_low_address();
// Now fix our return address.
// JrCs: this macro should be rewritten because the code generated by XCode 4.x
// change the value of the argument passed as parameter (multiboot_magic)
// FIX_RETURN_ADDRESS_USING_FIRST_ARG(multiboot_magic);
// We can now do just about anything, including return to our caller correctly.
// However, our caller must fix his return address if he wishes to return to
// his caller and so on and so forth.
/* Zero the BSS and initialize malloc */
initialize_runtime();
gMI = mi_p;
/* Set up a temporary bootArgs so we can call console output routines
like printf that check the v_display. Note that we purposefully
do not initialize anything else at this early stage.
We are reasonably sure we're already in text mode if GRUB booted us.
This is the same assumption that initKernBootStruct makes.
We could check the multiboot info I guess, but why bother?
*/
boot_args temporaryBootArgsData;
bzero(&temporaryBootArgsData, sizeof(boot_args));
bootArgs = &temporaryBootArgsData;
bootArgs->Video.v_display = VGA_TEXT_MODE;
// Install ramdisk and extra driver hooks
p_get_ramdisk_info = &multiboot_get_ramdisk_info;
p_ramdiskReadBytes = &multibootRamdiskReadBytes;
LoadExtraDrivers_p = &multiboot_LoadExtraDrivers;
// Since we call multiboot ourselves, its return address will be correct.
// That is unless it's inlined in which case it does not matter.
uint64_t bootdevice = multiboot( multiboot_magic, mi_orig); // mi_p);
if(bootdevice != BAD_BOOT_DEVICE)
{
// boot only returns to do a chain load.
for(;;)
{ // NOTE: boot only uses the last byte (the drive number)
common_boot(bootdevice);
if(chainbootflag)
chainLoad();
else
waitThenReload();
}
}
// We're about to exit and temporaryBootArgs will no longer be valid
bootArgs = NULL;
return bootdevice;
}
// Starts off in the multiboot context 1 MB high but eventually gets into low memory
// and winds up with a bootdevice in eax which is all that boot() wants
// This lets the stack pointer remain very high.
// If we were to call boot directly from multiboot then the whole multiboot_info
// would be on the stack which would possibly be using way too much stack.
void multiboot_to_boot(int multiboot_magic, struct multiboot_info *mi_orig)
{
hi_multiboot(multiboot_magic, mi_orig);
// Avoid returning to high-memory address which isn't valid in the segment
// we are now in.
// Calling sleep() ensures the user ought to be able to use Ctrl+Alt+Del
// because the BIOS will have interrupts on.
for(;;)
sleep(10);
// NOTE: *IF* we needed to return we'd have to fix up our return address to
// be in low memory using the same trick as below.
// However, there doesn't seem to be any point in returning to assembly
// particularly when the remaining code merely halts the processor.
}
///////////////////////////////////////////////////////////////////////////
// Ramdisk and extra drivers code

Archive Download the corresponding diff file

Revision: 2661