Esempio n. 1
0
// this func calculate the number of frames
// require for the ram and then acc to that
// create no. of frames which will be required for it
// and also mark the space which is preoccupied
// by the kernel
void init_mm(u32int ram_sz_bytes)
{
	// create a bitmap for the record
	// which blocks is allocated
	// and which isn't
	initFrames(ram_sz_bytes);
	// right now bit is full of zero 
	// means nothing is allocated yet
	// so we have place one to show that 
	// kernel is here you can't allocate
	// here
	allocate_kernel();
}
Esempio n. 2
0
/**
 * Load an x86 Linux kernel.
 *
 * @param loader        Loader internal data.
 */
__noreturn void linux_arch_load(linux_loader_t *loader)
{
	linux_params_t *params;
	size_t cmdline_size, setup_size, load_size;
	char *cmdline;
	void *virt;
	phys_ptr_t phys, initrd_max;
	list_t memory_map;
	status_t ret;

	static_assert(sizeof(linux_params_t) == PAGE_SIZE);
	static_assert(offsetof(linux_params_t, hdr) == LINUX_HEADER_OFFSET);

	// Allocate memory for the parameters data (the "zero page").
	params = memory_alloc(sizeof(linux_params_t), 0, 0x10000, 0x90000, MEMORY_TYPE_RECLAIMABLE, 0, NULL);
	memset(params, 0, sizeof(*params));

	// Read in the kernel header.
	ret = fs_read(loader->kernel, &params->hdr, sizeof(params->hdr), offsetof(linux_params_t, hdr));
	if (ret != STATUS_SUCCESS)
		boot_error("Error reading kernel header: %pS", ret);

	// Start populating required fields in the header. Don't set heap_end_ptr or
	// the CAN_USE_HEAP flag, as these appear to only be required by the 16-bit
	// entry point which we do not use.
	params->hdr.type_of_loader = 0xff;

	// Calculate the maximum command line size.
	cmdline_size = (params->hdr.version >= 0x0206) ? params->hdr.cmdline_size : 255;
	if (strlen(loader->cmdline) > cmdline_size)
		boot_error("Kernel command line is too long");

	// Allocate memory for command line.
	cmdline_size = round_up(cmdline_size + 1, PAGE_SIZE);
	cmdline = memory_alloc(cmdline_size, 0, 0x10000, 0x90000, MEMORY_TYPE_RECLAIMABLE, 0, NULL);
	strncpy(cmdline, loader->cmdline, cmdline_size);
	cmdline[cmdline_size] = 0;
	params->hdr.cmd_line_ptr = (uint32_t)((ptr_t)cmdline);

	// Determine the setup code size.
	if (params->hdr.setup_sects)
		setup_size = (params->hdr.setup_sects + 1) * 512;
	else
		setup_size = 5 * 512;

	// Load size is total file size minus setup size.
	load_size = loader->kernel->size - setup_size;

	// Allocate memory for the kernel image.
	virt = allocate_kernel(params, load_size, &phys);
	if (!virt)
		boot_error("Insufficient memory available for kernel image");

	params->hdr.code32_start = phys + params->hdr.code32_start - LINUX_BZIMAGE_ADDR;

	// Read in the kernel image.
	ret = fs_read(loader->kernel, virt, load_size, setup_size);
	if (ret != STATUS_SUCCESS)
		boot_error("Error reading kernel image: %pS", ret);

	// Load in the initrd(s).
	if (loader->initrd_size) {
		initrd_max = (params->hdr.version >= 0x0203)
			     ? params->hdr.initrd_addr_max
			     : 0x37ffffff;

		// It is recommended that the initrd be loaded as high as possible.
		virt = memory_alloc(
			round_up(loader->initrd_size, PAGE_SIZE), 0,
			0x100000, initrd_max + 1, MEMORY_TYPE_MODULES, MEMORY_ALLOC_HIGH, &phys);

		dprintf(
			"linux: loading initrd to 0x%" PRIxPHYS " (size: 0x%zx, max: 0x%" PRIxPHYS ")\n",
			phys, loader->initrd_size, initrd_max);

		linux_initrd_load(loader, virt);

		params->hdr.ramdisk_image = phys;
		params->hdr.ramdisk_size = loader->initrd_size;
	}

	// Set the video mode.
	linux_video_set(loader);

	// Perform pre-boot tasks.
	loader_preboot();

	// Get the final memory map and print it out for informational purposes.
	// Note that the memory_finalize() is necessary on EFI in order to free up
	// any internal allocations in the EFI memory map so that they will be free
	// to the kernel.
	dprintf("linux: final physical memory map:\n");
	memory_finalize(&memory_map);
	memory_map_dump(&memory_map);

	// Get platform code to do any setup it needs and enter the kernel.
	// For BIOS, this will obtain information usually obtained by the real-mode
	// bootstrap when using the 16-bit boot protocol, then jump to the 32-bit
	// entry point. For EFI, this will enter the kernel using the handover
	// protocol.
	linux_platform_load(loader, params);
}