今天开始学习ucore的lab。
按照lab0的文档,显示介绍了80386的4个工作模式:real-address mode, protected mode, SMM mode, virtual 8086 mode.
ia-32-architectures-software-developer-system-programming-manual-VOL3_Feb2014中的Figure 2-3. Transitions Among the Processor’s Operating Modes是4个mode FSM。
在Lab 0的2.6节介绍了ucore的编程方法:用C实现C++的OOP思想:interface(API)。在Absolute C++的Chap 6的tip里面讲了:princeple of encapsulation is on: separate "interface" and "implementation of class".
在http://www.tutorialspoint.com/cplusplus/cpp_interfaces.htm 里面讲了interface一般是用abstract class作为base class。
在 http://www.bottomupcs.com/abstration.html 详述了linux kernal, system with large C based code. 通过使用function pointer来模拟C++的interface/class的OOP。
在 understanding and using pointer in C 中的function pointer里面提到一个drawback: "One concern regarding the use of function pointers is a potentially slower running program. The processor may not be able to use branch prediction in conjunction with pipelining."
这印证了ucore lab0的说法:“Core 的面向对象编程方法,目前主要是采用了类似 C++的接口(interface)概念,即是让实现 细节不同的某类内核子系统(比如物理内存分配器、调度器,文件系统等)有共同的操作方式 ... 接口在 C 语言中,表现为一组函数指针的集合。放在 C++ 中,即为虚表。”
先复习一下 function pointer, structure in C.
1 /* 2 * function pointers in C as the interface in C++ 3 * used widely in linux kernal, or lab0 of ucore 4 * Jun 8, 2014 5 * 6 * http://www.bottomupcs.com/abstration.html#ftn.d5e116 7 */ 8 9 #include <stdio.h> 10 11 /* The API to implement */ 12 struct greet_api { 13 int (*say_hello)(char *name); 14 int (*say_goodbye)(void); 15 }; 16 17 /* Our implementation of the hello function */ 18 int say_hello_fn(char *name) { 19 printf("Hello %s\n", name); 20 return 0; 21 } 22 23 /* Our implementation of the goodbye function */ 24 int say_goodbye_fn(void) { 25 printf("Goodbye\n"); 26 return 0; 27 } 28 29 /* A struct implementing the API */ 30 /* 31 * Designated Initializers for Structures 32 * See <C primer plus 5th> 33 * the name of a function can be used to represent the address of the function 34 */ 35 struct greet_api greet_api = { .say_hello = say_hello_fn, .say_goodbye = 36 say_goodbye_fn }; 37 38 /* main() doesn't need to know anything about how the 39 * say_hello/goodbye works, it just knows that it does */ 40 int main(int argc, char *argv[]) { 41 greet_api.say_hello(argv[1]); 42 greet_api.say_goodbye(); 43 44 printf("%p, %p, %p\n", greet_api.say_hello, say_hello_fn, &say_hello_fn); 45 46 //exit(0); 47 return 0; 48 }
然后可以看看ucore是怎么用structure of function pointer去实现一个C++的interface。
在lab2/kern/mm/pmm.h里面的pmm_manager:
1 // pmm_manager is a physical memory management class. A special pmm manager - XXX_pmm_manager 2 // only needs to implement the methods in pmm_manager class, then XXX_pmm_manager can be used 3 // by ucore to manage the total physical memory space. 4 struct pmm_manager { 5 const char *name; // XXX_pmm_manager's name 6 void (*init)(void); // initialize internal description&management data structure 7 // (free block list, number of free block) of XXX_pmm_manager 8 void (*init_memmap)(struct Page *base, size_t n); // setup description&management data structcure according to 9 // the initial free physical memory space 10 struct Page *(*alloc_pages)(size_t n); // allocate >=n pages, depend on the allocation algorithm 11 void (*free_pages)(struct Page *base, size_t n); // free >=n pages with "base" addr of Page descriptor structures(memlayout.h) 12 size_t (*nr_free_pages)(void); // return the number of free pages 13 void (*check)(void); // check the correctness of XXX_pmm_manager 14 }; 15 16 extern const struct pmm_manager *pmm_manager;
然后在2.6.2.1 双向循环链表中学习了ucore中常用的数据结构。这在uc/os-II和freertos里面的freelistTable也用到了。
注意:ucore的double linked list 和C/C++里面的设计方法有点点区别。这是为了适应不同功能的双向链表:有保存task table的,有空闲内存块列表,或者、内存页链表等等。
Guide for OS LAB - based on ucore
- lab0: prepare environment
- lab1: boot/protect mode/stack/interrupt
- lab2: physical memory management
- lab3: virtual memory management
- lab4: kernel thread management
- lab5: user process management
- lab6: scheduling
- lab7: mutex/sync
- lab8: filesystem