Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2112760
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-09-01 15:47:00

1. boot目录中的代码流程
1.1 boot编译完成后是mbr在磁盘的第[1]扇区
boot扇区代码是bootsect.s 
a. 将自己从0x7c00-->0x9000,512=0x200, [0x90000,0x90200]
b. 加载setup,即将磁盘第2个扇区的setup加载到0x90200,共4个扇区[0x90200-0x90A00]
c. 加载system到0x10000(64K)处,从0x1000(64K)-0x90000(576K)都是system的代码
d. 跳到0x90200处的setup运行

1.2 setup.s的流程,编译完成后是setup在磁盘的第[2-6]扇区
a.获取mem的容量,显卡模式,硬盘信息
b.把[0x10000-0x90000]的内存移动到[0x0000-0x80000],即把system移动到了0x0处
c. 加载gdt idt,开启保护模式
d. 跳到0x0处,即system处

1.3 head.s的流程
a. 运行地址是0x0,重新设置idt gdt check_x87
b. 在0x00地址处设置页目录表1个[0x0-0x1000] 
    页表4个[0x1000-0x2000] [0x2000-0x3000] [0x3000-0x4000] [0x4000-0x5000]
c. 跳到main
1.4 linux0.12在磁盘上的分布

注: 上图出自《Linux内核完全注释(修正版v3.0).pdf》赵炯 

1.5 boot完成后内存地址分布如下所示: 
[0x67d8]               -->main 0x000067d8
[0x5cc0-0x64c0]  -->gdt 2k
[0x54c0-0x5cc0]  -->idt 2k
[0x54ac-0x54b4]  -->gdt_desc [8b]
[0x54ac-0x54b4]  -->idt_desc [8b]

[0x5450-0x54a8]  -->setup_paging
[0x5428-0x5450]  -->ignore_init
[0x5412-0x5428]  -->字符串 Unknown interrupt\n\r 
[0x5400-0x5412]   -->after_page_tables   -->函数占字节0x10
[0x5000-0x5400]  -->软盘缓冲区 [1k]
[0x4000-0x5000]  -->页3  [4k]
[0x3000-0x4000]  -->页表2  [4k]
[0x2000-0x3000]  -->页表1  [4k]
[0x1000-0x2000]  -->页表0  [4k]
[0x0000-0x1000]  -->页目录表 [4k]
注: 页目录表-->setup_paging的内容没错,后面的idt_desc的具体地址可能会有几个字节的错误,
错了没关系,知道这儿有什么就行了。


2. 几个问题
问题1.为什么head.s在system的最开始处
a. 将main.o与head.o调换一下,然后重新编译
  1. tools/system: boot/head.o init/main.o \
  2.         $(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS)
  3.     $(LD) $(LDFLAGS) init/main.o boot/head.o \    -->将head.o与main.o调换一下
  4.     $(ARCHIVES) \
  5.     $(DRIVERS) \
  6.     $(MATH) \
  7.     $(LIBS) \
  8.     -o tools/system > System.map
b.调试一下
  1. Next at t=0
  2. (0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b ; ea5be000f0
  3. <bochs:1> b 0x00
  4. <bochs:2> c
  5. (0) Breakpoint 1, 0x00000000 in ?? ()
  6. Next at t=425316395
  7. (0) [0x000000000000] 0008:00000000 (unk. ctxt): sub esp, 0x00000010 ; 83ec10
  8. <bochs:3> n
  9. Next at t=425316396
  10. (0) [0x000000000003] 0008:00000003 (unk. ctxt): mov eax, 0x00000002 ; b802000000
  11. <bochs:4> n
  12. Next at t=425316397
  13. (0) [0x000000000008] 0008:00000008 (unk. ctxt): int 0x80 ; cd80
  14. <bochs:5> n
  15. (0).[425316397] [0x000000000008] 0008:00000008 (unk. ctxt): int 0x80 ; cd80
  16. Next at t=425316398
  17. (0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b ; ea5be000f0
c. 调换后,发现0x0的代码来于main.o
  1. cong@msi:/work/os/linux12$ objdump -S init/main.o
  2. init/main.o: file format elf32-i386
  3. Disassembly of section .text:
  4. 00000000 <fork>:
  5. inline _syscall0(int,fork)
  6.    0:    83 ec 10     sub $0x10,%esp
  7.    3:    b8 02 00 00 00     mov $0x2,%eax
  8.    8:    cd 80     int $0x80
  9.    a:    89 44 24 0c     mov %eax,0xc(%esp)
  10.    e:    83 7c 24 0c 00     cmpl $0x0,0xc(%esp)
d.总结
这个是由链接器决定的,ld在链接时把head.o放在前面,就把head.o链接到了目标的最前面

问题2.在0x0处既有head.s的代码也有页表,这两个是不是冲突?
a. 下面是bochs的调试结果:
  1. Next at t=0
  2. (0) [0x0000fffffff0] f000:fff0 (unk. ctxt): jmpf 0xf000:e05b ; ea5be000f0
  3. <bochs:1> b 0x0                              -->在0x00处设断点
  4. <bochs:2> c
  5. (0) Breakpoint 1, 0x00000000 in ?? ()
  6. Next at t=606666395
  7. (0) [0x000000000000] 0008:00000000 (unk. ctxt): mov eax, 0x00000010 ; b810000000
  8. <bochs:3> n
  9. Next at t=606666396
  10. (0) [0x000000000005] 0008:00000005 (unk. ctxt): mov ds, ax ; 8ed8
  11. <bochs:4> n
  12. Next at t=606666397
  13. (0) [0x000000000007] 0008:00000007 (unk. ctxt): mov es, ax ; 8ec0
  14. <bochs:5>
  15. Next at t=606666398
  16. (0) [0x000000000009] 0008:00000009 (unk. ctxt): mov fs, ax ; 8ee0
  17. <bochs:6>
  18. Next at t=606666399
  19. (0) [0x00000000000b] 0008:0000000b (unk. ctxt): mov gs, ax ; 8ee8
  20. <bochs:7>
  21. Next at t=606666400
  22. (0) [0x00000000000d] 0008:0000000d (unk. ctxt): lss esp, ds:0x0002ab80 ; 0fb22580ab0200
  23. <bochs:8>
  24. Next at t=606666401
  25. (0) [0x000000000014] 0008:00000014 (unk. ctxt): call .+90 (0x00000073) ; e85a000000   -->call setup_idt
  26. <bochs:9> n
  27. Next at t=606667690
  28. (0) [0x000000000019] 0008:00000019 (unk. ctxt): call .+133 (0x000000a3) ; e885000000  -->call setup_gdt
  29. <bochs:10> n
  30. Next at t=606667693
  31. (0) [0x00000000001e] 0008:0000001e (unk. ctxt): mov eax, 0x00000010 ; b810000000
  32. <bochs:11>
  33. Next at t=606667694
  34. (0) [0x000000000023] 0008:00000023 (unk. ctxt): mov ds, ax ; 8ed8
  35. <bochs:12>
  36. Next at t=606667695
  37. (0) [0x000000000025] 0008:00000025 (unk. ctxt): mov es, ax ; 8ec0
  38. <bochs:13>
  39. Next at t=606667696
  40. (0) [0x000000000027] 0008:00000027 (unk. ctxt): mov fs, ax ; 8ee0
  41. <bochs:14>
  42. Next at t=606667697
  43. (0) [0x000000000029] 0008:00000029 (unk. ctxt): mov gs, ax ; 8ee8
  44. <bochs:15>
  45. Next at t=606667698
  46. (0) [0x00000000002b] 0008:0000002b (unk. ctxt): lss esp, ds:0x0002ab80 ; 0fb22580ab0200
  47. <bochs:16>
  48. Next at t=606667699
  49. (0) [0x000000000032] 0008:00000032 (unk. ctxt): xor eax, eax ; 31c0
  50. <bochs:17> n
  51. Next at t=606667700
  52. (0) [0x000000000034] 0008:00000034 (unk. ctxt): inc eax ; 40
  53. <bochs:18>
  54. Next at t=606667701
  55. (0) [0x000000000035] 0008:00000035 (unk. ctxt): mov dword ptr ds:0x00000000, eax ; a300000000
  56. <bochs:19>
  57. Next at t=606667702
  58. (0) [0x00000000003a] 0008:0000003a (unk. ctxt): cmp dword ptr ds:0x00100000, eax ; 390500001000
  59. <bochs:20>
  60. Next at t=606667703
  61. (0) [0x000000000040] 0008:00000040 (unk. ctxt): jz .-14 (0x00000034) ; 74f2
  62. <bochs:21>
  63. Next at t=606667704
  64. (0) [0x000000000042] 0008:00000042 (unk. ctxt): mov eax, cr0 ; 0f20c0
  65. <bochs:22> n
  66. Next at t=606667705
  67. (0) [0x000000000045] 0008:00000045 (unk. ctxt): and eax, 0x80000011 ; 2511000080
  68. <bochs:23>
  69. Next at t=606667706
  70. (0) [0x00000000004a] 0008:0000004a (unk. ctxt): or eax, 0x00000002 ; 83c802
  71. <bochs:24>
  72. Next at t=606667707
  73. (0) [0x00000000004d] 0008:0000004d (unk. ctxt): mov cr0, eax ; 0f22c0
  74. <bochs:25>
  75. Next at t=606667708
  76. (0) [0x000000000050] 0008:00000050 (unk. ctxt): call .+5 (0x0000005a) ; e805000000   -->call check_x87
  77. <bochs:26>
  78. Next at t=606667716
  79. (0) [0x000000000055] 0008:00000055 (unk. ctxt): jmp .+21414 (0x00005400) ; e9a6530000   --> jmp after_page_tables
  80. <bochs:27> n
  81. Next at t=606667717
  82. (0) [0x000000005400] 0008:00005400 (unk. ctxt): push 0x00000000           ; 6a00        -->一下子跳到了0x5400处
  83. <bochs:28> n
    Next at t=606667718
    (0) [0x000000005402] 0008:00005402 (unk. ctxt): push 0x00000000           ; 6a00
    <bochs:29> n 
    Next at t=606667719
    (0) [0x000000005404] 0008:00005404 (unk. ctxt): push 0x00000000           ; 6a00
    <bochs:30> n
    Next at t=606667720
    (0) [0x000000005406] 0008:00005406 (unk. ctxt): push 0x00005412           ; 6812540000
    <bochs:31> n 
    Next at t=606667721
    (0) [0x00000000540b] 0008:0000540b (unk. ctxt): push 0x000067d8           ; 68d8670000
    <bochs:32> n
    Next at t=606667722
    (0) [0x000000005410] 0008:00005410 (unk. ctxt): jmp .+62 (0x00005450)     ; eb3e     --> jmp setup_paging

b.从上面的调试可以看出:
在0x00地址处设置页目录表1个[0x0-0x1000]  页表4个[0x1000-0x5000]
call setup_idt       

      -->setup_idt函数本身的地址是0x73,但中断处理函数的ignore_int与idt_descr都在0x50000以后
call setup_gdt
        -->setup_gdt函数本身的地址是0xa3,但gdt_descr在0x50000以后
call check_x87
        -->check_x87函数本身的地址是0x5a
setup_idt  setup_gdt  check_x87的地址虽然会被页表所覆盖,但是它们只需要执行一次,执行完再被覆盖也没有关系
  1. setup_idt:
  2.     lea ignore_int,%edx
  3. (0) [0x000000000073] 0008:00000073 (unk. ctxt): lea edx, dword ptr ds:0x00005428 ; 8d1528540000

  4. lidt idt_descr
  5. Next at t=931567493
  6. (0) [0x00000000009b] 0008:0000009b (unk. ctxt): lidt ds:0x000054ae ; 0f011dae540000

  7. lgdt gdt_descr
  8. Next at t=931567496
  9. (0) [0x0000000000a3] 0008:000000a3 (unk. ctxt): lgdt ds:0x000054b6 ; 0f0115b6540000


阅读(1544) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~