今回はmain関数の中で「copy_boot_params」の次に呼び出している「init_heap」を見てみます。
====
static void init_heap(void){char *stack_end;/* ヒープを使うかどうか */if (boot_params.hdr.loadflags & CAN_USE_HEAP) {asm("leal %P1(%%esp),%0": "=r" (stack_end) : "i" (-STACK_SIZE));/* ヒープのオフセットリミットをheap_end_ptr に格納する */heap_end = (char *)((size_t)boot_params.hdr.heap_end_ptr + 0x200);if (heap_end > stack_end)heap_end = stack_end;} else {/* ブートプロトコル2.0以前のものはヒープを用意できない */puts("WARNING: Ancient bootloader, some functionality ""may be limited!¥n");}}
====
boot_params.hdr.loadflagsの値を見てヒープを使うかどうかを判定しています。
ブートプロトコルが2.02以降ならば基本的にif文の内側に入ってきます。
if文の内側ではヒープのオフセットリミットをheap_end_ptrメンバに格納しています。
boot_params.hdrは前回見たcopy_boot_paramsにてコピーして来たものです。
bott_params.hdrは「setup_header」という構造体でbootparam.hで定義しています。
arch/x86/include/asm/bootparam.h
====
struct setup_header {__u8 setup_sects;__u16 root_flags;__u32 syssize;__u16 ram_size;#define RAMDISK_IMAGE_START_MASK 0x07FF#define RAMDISK_PROMPT_FLAG 0x8000#define RAMDISK_LOAD_FLAG 0x4000__u16 vid_mode;__u16 root_dev;__u16 boot_flag;__u16 jump;__u32 header;__u16 version;__u32 realmode_swtch;__u16 start_sys;__u16 kernel_version;__u8 type_of_loader;__u8 loadflags;#define LOADED_HIGH (1<<0)#define QUIET_FLAG (1<<5)#define KEEP_SEGMENTS (1<<6)#define CAN_USE_HEAP (1<<7)__u16 setup_move_size;__u32 code32_start;__u32 ramdisk_image;__u32 ramdisk_size;__u32 bootsect_kludge;__u16 heap_end_ptr;__u16 _pad1;__u32 cmd_line_ptr;__u32 initrd_addr_max;__u32 kernel_alignment;__u8 relocatable_kernel;__u8 _pad2[3];__u32 cmdline_size;__u32 hardware_subarch;__u64 hardware_subarch_data;__u32 payload_offset;__u32 payload_length;__u64 setup_data;} __attribute__((packed));
=====
でかい。
前回も見たheader.Sの中での「hdr」のアドレス部分からの抜粋を下記に。
=====
hdr:setup_sects: .byte SETUPSECTSroot_flags: .word ROOT_RDONLYsyssize: .long SYSSIZEram_size: .word RAMDISKvid_mode: .word SVGA_MODEroot_dev: .word ROOT_DEVboot_flag: .word 0xAA55
=====
先述の構造体の「boot_flag」までがここまでと対応しています。
さらにheader.Sを見て行きましょう。
====
.globl _start_start:...(省略)...start_sys_seg: .word SYSSEG.word kernel_version-512 # pointing to kernel version string# above section of header is compatible# with loadlin-1.5 (header v1.5). Don't# change it.type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin,# Bootlin, SYSLX, bootsect...)# See Documentation/i386/boot.txt for# assigned ids# flags, unused bits must be zero (RFU) bit within loadflagsloadflags:LOADED_HIGH = 1 # If set, the kernel is loaded highCAN_USE_HEAP = 0x80 # If set, the loader also has set# heap_end_ptr to tell how much# space behind setup.S can be used for# heap purposes.# Only the loader knows what is free...(省略)...payload_offset: .long input_datapayload_length: .long input_data_end-input_datasetup_data: .quad 0 # 64-bit physical pointer to# single linked list of# struct setup_data
====
長いので一部省略していますが、構造体定義と照らし合わせてみれば最後まで値が入ってくることが分かります。
0 件のコメント:
コメントを投稿