0

I am studying Kernel development. Using a book I have come to a point. However, I cannot realy understand the affect of global descriptor table. My GDT is as follows:

gdt_star:

gdt_null:
dd 0x0      
dd 0x0

gdt_code:
dw 0xffff   
dw 0x0000
db 0x00     
db 10011011b
db 11001111b
db 0x0      

gdt_data:
dw 0xffff
dw 0x0
db 0x00
db 10010010b
db 11001111b
db 0x0              

gdt_end:

gdt_descriptor:
dw gdt_end - gdt_star - 1
dd gdt_star

CODE_SEG equ gdt_code - gdt_star
DATA_SEG equ gdt_data - gdt_star

After loading gdt and assigning DATA_SEG to ds, ss, es, fs, gs registers; my assembly code jumps to c code. Data segment base address is 0x00000000 and the limit is 0xffff. Shouldn't it be impossible to put a value to 0x100000 memory address?

Thank you

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
user2972185
  • 231
  • 3
  • 12
  • You've edited the question to be a different one, by changing the graularity bit. It's almost always a better idea to ask a new question if that's the case. – paxdiablo Aug 18 '14 at 01:58

1 Answers1

1

The limit is scaled by the granularity.

For example, if you use page granularity (4K), a limit of 0xfffff will give you access to the entire 4G address space.

The granularity is dictated by (from memory) the second db in each GDT entry. Because the top bit of that value is 1, the 4K granularity is selected.

If you look at the following image, you'll see the limits of what you can access in the data segment:

enter image description here

gdt_data:
dw 0xffff     Segment limit b15..b0.
dw 0x0        Base address b15..b0.
db 0x00       Base address b23..b16.
db 10010010b  Present (1 bit) = yes.
              Data protection level (2 bits) = 0 (highest).
              Selector (1 bit) = code/data.
              Type (4 bits) read/write.
db 11001111b  Granularity (1 bit) = 4k.
              32-bit selector (1 bit) = 32 bits.
              Unused (1 bit).
              Segment limit b19..b16.
db 0x0        Base address b31..b24.

Hence your base address is 0x0000.0000 and segment limit is 0xf.ffff with 4k scaling. That allows addresses from 0x0000.0000 up to 0xffff.ffff. In other words, a full 4G address space.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Thank you. How can you assign `0xfffff` to a 2 bytes area. Is is a typo?When I change the gdt in accordance with your explanation, I can put value to `0x300000`. I have updated my question will you please check it? – user2972185 Aug 17 '14 at 03:13
  • The base and limit are in multiple sections within the gdt. As well as the 16-bit word, there are more bits in the other values which are used as well. See http://en.m.wikipedia.org/wiki/Global_Descriptor_Table for a graphic showing this. Base address has 32 bits and limit has 20 bits. – paxdiablo Aug 18 '14 at 01:35
  • Ok. Thank you I understand that. But I still can put data to a memory address which is beyond the limit + base address. Why this happens? – user2972185 Aug 18 '14 at 01:44