void start_kernel(void)分析 ! \linux-1.0\init\main.c

//启动系统内核
//asmlinkage 为通过堆栈传递参数,默认为通过寄存器传递参数。
asmlinkage void start_kernel(void)
{
/*
 * Interrupts are still disabled. Do necessary setups, then
 * enable them
 */
      //设置中断向量表
	set_call_gate(&default_ldt,lcall7);
      //设定初始化设备地址
 	ROOT_DEV = ORIG_ROOT_DEV;
	// 设定设备信息地址
 	drive_info = DRIVE_INFO;
	//设定屏幕信息地址
 	screen_info = SCREEN_INFO;
	//设定aux 设备当前地址
	aux_device_present = AUX_DEVICE_INFO;

	//设定内存末端值
	memory_end = (1<<20) + (EXT_MEM_K<<10);
	memory_end &= PAGE_MASK;

	//设定临时盘的大小
	ramdisk_size = RAMDISK_SIZE;

	//拷贝命令行
	copy_options(command_line,COMMAND_LINE);

	//如果内存大于16M 设定内存末端为16M
#ifdef CONFIG_MAX_16M
	if (memory_end > 16*1024*1024)
		memory_end = 16*1024*1024;
#endif
      //设定root 的多位标志位
	if (MOUNT_ROOT_RDONLY)
		root_mountflags |= MS_RDONLY;
	//如果最末端大于1M 设定内存开始点和最低内存开始点
	if ((unsigned long)&end >= (1024*1024)) {
		memory_start = (unsigned long) &end;
		low_memory_start = PAGE_SIZE;
	} 
	else
	{
	      //如果内存不大于1M ;设定内存开始点为1M处, 最低内存开始为end;
		memory_start = 1024*1024;
		low_memory_start = (unsigned long) &end;
	}

	//低内存开始点对齐
	low_memory_start = PAGE_ALIGN(low_memory_start);
	//页缓存区初始化
	memory_start = paging_init(memory_start,memory_end);

       //设定EISA 线路标志	
	if (strncmp((char*)0x0FFFD9, "EISA", 4) == 0)
		EISA_bus = 1;

	//设置各个中断向量表.
	trap_init();
	//初始化中断请求
	init_IRQ();
	//日程初始化
	sched_init();
	//解析命令行
	parse_options(command_line);
#ifdef CONFIG_PROFILE
	prof_buffer = (unsigned long *) memory_start;
	prof_len = (unsigned long) &end;
	prof_len >>= 2;
	memory_start += prof_len * sizeof(unsigned long);
#endif
      //分配内存 初始化
	memory_start = kmalloc_init(memory_start,memory_end);
       //
	memory_start = chr_dev_init(memory_start,memory_end);
	memory_start = blk_dev_init(memory_start,memory_end);
	 //设定允许中断
	sti();
	//校准延时
	calibrate_delay();
#ifdef CONFIG_INET
       //网络初始化
	memory_start = net_dev_init(memory_start,memory_end);
#endif
#ifdef CONFIG_SCSI
       //scsi 设备初始化
	memory_start = scsi_dev_init(memory_start,memory_end);
#endif
      //节点初始化
	memory_start = inode_init(memory_start,memory_end);
       //文件表初始化
	memory_start = file_table_init(memory_start,memory_end);
	//内存区初始化
	mem_init(low_memory_start,memory_start,memory_end);
	//缓存初始化
	buffer_init();
	// 时间初始化
	time_init();
	//软盘初始化
	floppy_init();
	//sock 初始化
	sock_init();
#ifdef CONFIG_SYSVIPC
      //ipc 初始化
	ipc_init();
#endif
     //设定允许中断
	sti();
	
	/*
	 * check if exception 16 works correctly.. This is truly evil
	 * code: it disables the high 8 interrupts to make sure that
	 * the irq13 doesn't happen. But as this will lead to a lockup
	 * if no exception16 arrives, it depends on the fact that the
	 * high 8 interrupts will be re-enabled by the next timer tick.
	 * So the irq13 will happen eventually, but the exception 16
	 * should get there first..
	 */
	 //hard_math设定为是时进行响应处理
	if (hard_math) {
		unsigned short control_word;

		printk("Checking 386/387 coupling... ");
		timer_table[COPRO_TIMER].expires = jiffies+50;
		timer_table[COPRO_TIMER].fn = copro_timeout;
		timer_active |= 1<<COPRO_TIMER;
		__asm__("clts ; fninit ; fnstcw %0 ; fwait":"=m" (*&control_word));
		control_word &= 0xffc0;
		__asm__("fldcw %0 ; fwait": :"m" (*&control_word));
		outb_p(inb_p(0x21) | (1 << 2), 0x21);
		__asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait");
		timer_active &= ~(1<<COPRO_TIMER);
		if (!fpu_error)
			printk("Ok, fpu using %s error reporting.\n",
				ignore_irq13?"exception 16":"irq13");
	}
	//如果没有设定数字仿真设定进行报错
#ifndef CONFIG_MATH_EMULATION
	else {
		printk("No coprocessor found and no math emulation present.\n");
		printk("Giving up.\n");
		for (;;) ;
	}
#endif

       //设定系统版本 并打印出来
	system_utsname.machine[1] = '0' + x86;
	printk(linux_banner);

      //设定到用户模式
	move_to_user_mode();
	//初始化完成, 创建子进程进入到shell界面.
	if (!fork())		/* we count on this going ok */
		init();
/*
 * task[0] is meant to be used as an "idle" task: it may not sleep, but
 * it might do some general things like count free pages or it could be
 * used to implement a reasonable LRU algorithm for the paging routines:
 * anything that can be useful, but shouldn't take time from the real
 * processes.
 *
 * Right now task[0] just does a infinite idle loop.
 */
      //父进程进行休眠。
	for(;;)
		idle();
}

int main(void) { /* USER CODE BEGIN 1 */ uint8_t ucDevType; volatile uint32_t ii; MPU_Config(); /* USER CODE END 1 */ /* Enable I-Cache---------------------------------------------------------*/ SCB_EnableICache(); /* Enable D-Cache---------------------------------------------------------*/ SCB_EnableDCache(); /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_CRC_Init(); MX_FMC_Init(); MX_I2C1_Init(); MX_LTDC_Init(); MX_QUADSPI_Init(); MX_RNG_Init(); MX_SDMMC1_SD_Init(); MX_SPI3_Init(); MX_USART1_UART_Init(); MX_USART3_UART_Init(); MX_DMA2D_Init(); MX_TouchGFX_Init(); /* USER CODE BEGIN 2 */ bsp_InitUart(); bsp_InitDWT(); bsp_InitDS18B20(); // for(ii = 0;ii < 1000000; ii++) GPIOB->BSRR = GPIO_PIN_1 << 16; // if(!ps2is) // { // bsp_InitPS2(); // PS2_StartWork(); // bsp_DelayMS(200); // ucDevType = PS2_GetDevceType(); // if(ucDevType == PS2_KEYBOARD) // { // ps2is = 1; //// key.setVisible(1); // PS2_InitKeyboard(); // } // PS2_StopWork(); /* 停止PS2中断 */ // } //AppTaskCreate (); tx_kernel_enter(); comClearRxFifo(CounterCom2); comClearRxFifo(CounterCom); comClearRxFifo(COM6); comClearTxFifo(CounterCom2); comClearTxFifo(CounterCom); comClearTxFifo(COM6); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }解释这部分代码
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值